fitsh-0.9.2/0000755000175000017500000000000012772016355011263 5ustar apalapalfitsh-0.9.2/config.h.in0000644000175000017500000000100112771247043013275 0ustar apalapal/*****************************************************************************/ /* Main configuration file for the `fitsh` package */ /*****************************************************************************/ #define FITSH_PACKAGE_NAME "fitsh" #define FITSH_VERSION "@FITSH_VERSION@" #define FITSH_RELEASE_DATE "@FITSH_RELEASE@" #define FITSH_MAINT_RNAME "Pal, Andras" #define FITSH_MAINT_EMAIL "apal@szofi.net" /*****************************************************************************/ fitsh-0.9.2/prepare0000755000175000017500000000041212117332304012630 0ustar apalapal#!/bin/sh AUTOCONF=${AUTOCONF:-autoconf} rm -r -f ./autom4te.cache ./configure ./config.cache ./config.status ./config.log if test "x$1" = "xclean" ; then exit 0 elif ${AUTOCONF} ; then rm -r -f autom4te.cache exit 0 else rm -r -f autom4te.cache exit 1 fi fitsh-0.9.2/doc/0000755000175000017500000000000012772016355012030 5ustar apalapalfitsh-0.9.2/doc/man.brief0000644000175000017500000000166412772016322013615 0ustar apalapalfiarith evaluating arithmetic expressions on images as operands ficalib performing various calibration steps on the input images ficombine combining (most frequently, averaging) a set of images ficonv obtaining and evaluating convolution transformations fiheader reading and manipulating FITS header keywords fiign low-level manipulation of masks associated to FITS images fiinfo providing information or image stamps for images fiphot performing photometry on normal or subtracted images firandom generates artificial object lists and simulated images fistar detecting and characterizing point-like sources fitrans performing spatial transformations on the input image grcollect performing transposition on the input tabulated data grmatch pairing lines by involving identifier or cross matching grtrans transforming coordinate lists or fitting such transformations lfit general purpose evaluation and regression analysis tool fitsh-0.9.2/doc/examples/0000755000175000017500000000000012772016355013646 5ustar apalapalfitsh-0.9.2/doc/examples/firandom/0000755000175000017500000000000012772016355015445 5ustar apalapalfitsh-0.9.2/doc/examples/firandom/Makefile.in0000644000175000017500000000743412104734067017516 0ustar apalapalSHELL=/bin/sh FIRANDOM=../../../src/firandom TARGETS=uniform.fits \ globularcluster.fits \ coma1.fits \ coma2.fits \ background.fits \ vignetting.fits \ grid1.fits \ grid2.fits \ grid3.fits all: $(TARGETS) .PHONY: all clean # Simple image: 2000 uniformly (both in mag and spatially) distributed # stars, all of them have a fwhm of 2.3. Background has gaussian # distribution with a mean of 500 (thus, sky) and stddev of 10 (skysigma). uniform.fits: $(FIRANDOM) --size 512,512 --sky "g(500,10)" \ --list "f=4.3, 2000*[x=r(-1,1),y=r(-1,1),m=r(11,15)]" \ --mag-flux 10,100000 --bitpix -32 --output uniform.fits # A globular cluster: 2000 stars with a gaussian spatial distribution # (being located at the center and having an fwhm of 0.1 of the image size), # and some field stars (200 brighter and 2000 fainter...). globularcluster.fits: $(FIRANDOM) -s 512,512 -m "g(500,10)" \ -l "f=2.3, 2000*[x=g(0,0.2),y=g(0,0.2),m=r(11,15)],200*[x=r(-1,1),y=r(-1,1),m=r(10,16)],2000*[x=r(-1,1),y=r(-1,1),m=r(13,18)]" \ --mag-flux 10,10000 -b -32 -o globularcluster.fits # The coma-effect. The star profile is described by the parameters # s, d and k. s is the sigma value of a gaussian profile (the f, fwhm # is always 2.34 times larger than s). The d and k vales are the deviation # momenta, so the profile can be described by the equation # exp ( - 1/2 x M^-1 x ), where M is the matrix # [ s+d k ] # [ ] # [ k s-d ]. # The strength of the effect can be described with this COMA=0.2 # parameter. $(COMA) should be between 0 and 1. # The ellipticity of the stars can be described by two set of parameters: # this s, d and k _or_ by f (fwhm), e (ellipticity) and p (position angle) # (see other examples below). coma1.fits: $(FIRANDOM) -s 512,512 -m "g(500,10)" \ -l "1000*[x=r(-1,1),y=r(-1,1),m=r(10,15),s=1.5,d=+$(COMA)*s*(x^2-y^2),k=+2*$(COMA)*s*x*y]" \ --mag-flux 10,10000 -b -32 -o coma1.fits # Another type of coma effect: the sign is changed in d and k. coma2.fits: $(FIRANDOM) -s 512,512 -m "g(500,10)" \ -l "1000*[x=r(-1,1),y=r(-1,1),m=r(10,15),s=1.5,d=-$(COMA)*s*(x^2-y^2),k=-2*$(COMA)*s*x*y]" \ --mag-flux 10,10000 -b -32 -o coma2.fits # The background is not constant... background.fits: $(FIRANDOM) -s 512,512 -m "g(500,10)+x*20-y*8" \ -l "4000*[x=r(-1,1),y=r(-1,1),m=r(10,17)]" \ --mag-flux 10,10000 -b -32 -o background.fits # the simulation of the vignetting effect: vignetting.fits: $(FIRANDOM) -s 512,512 -m "200+600*(1-0.4*(x^2+y^2))+g(0,10)" \ -l "f=2.7,5000*[x=r(-1,1),y=r(-1,1),m=r(10,15)-2.5*lg(1-0.4*(x^2+y^2))]" \ --mag-flux 10,10000 -b -32 -o vignetting.fits # An equivalent way, the flux of the stars can be defined directly, # using the parameter 'i'. If the flux of the stars are specified by only # this parameter, the --max-flux switch can be omitted (however, it # can always be omitted, the default value is --max-flux 10,10000 ;)). # -l "f=2.7,5000*[x=r(-1,1),y=r(-1,1),i=(1-0.4*(x^2+y^2))*10000*10^(-0.4*r(0,5))]" \ # A perfect grid: in a block of N*[...], the global variable 'n' is changed # between 0 and N-1 so it can be used for generating grids. grid1.fits: $(FIRANDOM) -s 512,512 -m "g(500,10)" \ -l "f=2.5,100*[x=-0.5+0.1*div(n,10),y=-0.5+0.1*mod(n,10),m=r(10,12)]" \ --mag-flux 10,10000 -b -32 -o grid1.fits # Another grid which is not so perfect... grid2.fits: $(FIRANDOM) -s 512,512 -m "g(500,10)" \ -l "f=2.5,100*[x=-0.7+0.14*div(n,10)+r(0,0.04),y=-0.7+0.14*mod(n,10)+r(0,0.04),m=r(10,12)]" \ --mag-flux 10,10000 -b -32 -o grid2.fits # Another grid where other parameters (fwhm, ellipticity) are also varying # definitely, and the flux is constant: grid3.fits: $(FIRANDOM) -s 512,512 -m "g(500,10)" \ -l "100*[x=-0.7+0.14*div(n,10),y=-0.7+0.14*mod(n,10),m=10,f=1.0+0.2*div(n,10),e=0.04*mod(n,10),p=30]" \ --mag-flux 10,10000 -b -32 -o grid3.fits clean: rm -f $(TARGETS) fitsh-0.9.2/doc/examples/Makefile.in0000644000175000017500000000013711237342460015706 0ustar apalapalSHELL=/bin/sh .PHONY: all clean all: $(MAKE) -C firandom clean: $(MAKE) -C firandom clean fitsh-0.9.2/doc/Makefile.in0000644000175000017500000000016311657533614014100 0ustar apalapalSHELL=/bin/sh .PHONY: all clean all: $(MAKE) -C examples clean: $(MAKE) -C examples clean rm -f -r help2man fitsh-0.9.2/COPYING0000644000175000017500000007733011077127614012326 0ustar apalapal 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 fitsh-0.9.2/configure.mingw320000755000175000017500000000032012766041157014453 0ustar apalapal#!/bin/sh MINGW_BIN_PREFIX=i586-mingw32msvc HOST=win32 CC=${MINGW_BIN_PREFIX}-gcc \ AR=${MINGW_BIN_PREFIX}-ar \ LD=${MINGW_BIN_PREFIX}-ld \ RANLIB=${MINGW_BIN_PREFIX}-ranlib \ ./configure --host=${HOST} $@ fitsh-0.9.2/configure.mingw640000755000175000017500000000032212766041172014457 0ustar apalapal#!/bin/sh MINGW_BIN_PREFIX=x86_64-w64-mingw32 HOST=win64 CC=${MINGW_BIN_PREFIX}-gcc \ AR=${MINGW_BIN_PREFIX}-ar \ LD=${MINGW_BIN_PREFIX}-ld \ RANLIB=${MINGW_BIN_PREFIX}-ranlib \ ./configure --host=${HOST} $@ fitsh-0.9.2/configure.ac0000644000175000017500000004130412771514505013552 0ustar apalapal# Initialize autoconf: AC_INIT(fitsh, 0.9.2, apal@szofi.net) RELEASE_DATE=2016.09.23 ############################################################################### # =========================================================================== # http://www.nongnu.org/autoconf-archive/ax_cflags_gcc_option.html # =========================================================================== # # SYNOPSIS # # AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) # # DESCRIPTION # # AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like # "checking CFLAGS for gcc -fvomit-frame ... yes" and adds the optionflag # to CFLAGS if it is understood. You can override the shellvar-default of # CFLAGS of course. The order of arguments stems from the explicit macros # like AX_CFLAGS_WARN_ALL. # # The cousin AX_CXXFLAGS_GCC_OPTION would check for an option to add to # CXXFLAGS - and it uses the autoconf setup for C++ instead of C (since it # is possible to use different compilers for C and C++). # # The macro is a lot simpler than any special AX_CFLAGS_* macro (or # ac_cxx_rtti.m4 macro) but allows to check for arbitrary options. # However, if you use this macro in a few places, it would be great if you # would make up a new function-macro and submit it to the ac-archive. # # - $1 option-to-check-for : required ("-option" as non-value) # - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the other case) # - $3 action-if-found : add value to shellvariable # - $4 action-if-not-found : nothing # # Note: in earlier versions, $1-$2 were swapped. We try to detect the # situation and accept a $2=~/-/ as being the old option-to-check-for. # # There are other variants that emerged from the original macro variant # which did just test an option to be possibly added. However, some # compilers accept an option silently, or possibly for just another option # that was not intended. Therefore, we have to do a generic test for a # compiler family. For gcc we check "-pedantic" being accepted which is # also understood by compilers who just want to be compatible with gcc # even when not being made from gcc sources. # # See also: AX_CFLAGS_SUN_OPTION, AX_CFLAGS_HPUX_OPTION, # AX_CFLAGS_AIX_OPTION, and AX_CFLAGS_IRIX_OPTION. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # # 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 2 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 . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$2])dnl AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], VAR,[VAR="no, unknown" AC_LANG_SAVE AC_LANG_C ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_TRY_COMPILE([],[return 0;], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" AC_LANG_RESTORE ]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_ifvaln($4,$4) ;; *) m4_ifvaln($3,$3,[ if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" fi ]) ;; esac AS_VAR_POPDEF([VAR])dnl AS_VAR_POPDEF([FLAGS])dnl ]) dnl the only difference - the LANG selection... and the default FLAGS AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_OLD], [dnl AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$2])dnl AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], VAR,[VAR="no, unknown" AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_TRY_COMPILE([],[return 0;], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" AC_LANG_RESTORE ]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_ifvaln($4,$4) ;; *) m4_ifvaln($3,$3,[ if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" fi ]) ;; esac AS_VAR_POPDEF([VAR])dnl AS_VAR_POPDEF([FLAGS])dnl ]) dnl ------------------------------------------------------------------------- AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$1])dnl AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], VAR,[VAR="no, unknown" AC_LANG_SAVE AC_LANG_C ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_TRY_COMPILE([],[return 0;], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" AC_LANG_RESTORE ]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_ifvaln($4,$4) ;; *) m4_ifvaln($3,$3,[ if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" fi ]) ;; esac AS_VAR_POPDEF([VAR])dnl AS_VAR_POPDEF([FLAGS])dnl ]) dnl the only difference - the LANG selection... and the default FLAGS AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$1])dnl AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], VAR,[VAR="no, unknown" AC_LANG_SAVE AC_LANG_CPLUSPLUS ac_save_[]FLAGS="$[]FLAGS" for ac_arg dnl in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC # do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` AC_TRY_COMPILE([],[return 0;], [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) done FLAGS="$ac_save_[]FLAGS" AC_LANG_RESTORE ]) case ".$VAR" in .ok|.ok,*) m4_ifvaln($3,$3) ;; .|.no|.no,*) m4_ifvaln($4,$4) ;; *) m4_ifvaln($3,$3,[ if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" fi ]) ;; esac AS_VAR_POPDEF([VAR])dnl AS_VAR_POPDEF([FLAGS])dnl ]) AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, [AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, [AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])]) ############################################################################### # our default $(CFLAGS) are: if test -n "$CFLAGS" ; then cflags_default=no elif test "${ac_cv_env_host_alias_value}" == "win32" ; then HOST=win32 CFLAGS="-Wall -pedantic -O3 -Wno-strict-aliasing -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHOST_WIN32" cflags_default=yes elif test "${ac_cv_env_host_alias_value}" == "win64" ; then HOST=win64 CFLAGS="-Wall -pedantic -O3 -Wno-strict-aliasing -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHOST_WIN32 -DHOST_WIN64" cflags_default=yes elif test "${CC}" == "tcc"; then CFLAGS="-Wall -pedantic -O3 -Wno-strict-aliasing -fPIC -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE" cflags_default=yes else CFLAGS="-Wall -pedantic -ansi -O3 -Wno-strict-aliasing -fPIC -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE" cflags_default=yes fi # some additional: CFLAGS="${CFLAGS} -D_FITSH_SOURCE" dynamic_extensions=yes AC_ARG_ENABLE(dynamic-extensions, [ --enable-dynamic-extensions `lfit` may use dynamic extensions at run-time (default: yes)], [ if test "x$enableval" = "xno" ; then dynamic_extensions=no; else dynamic_extensions=yes; fi ]) # check compiler: AC_PROG_CC # check archiver: test -n "$AR" || AR=ar AC_CHECK_PROG(ac_prog_ar,$AR,$AR,false) # check linker: test -n "$LD" || LD=ld AC_CHECK_PROG(ac_prog_ld,$LD,$LD,false) # check ranlib: test -n "$RANLIB" || RANLIB=ranlib AC_CHECK_PROG(ac_prog_ranlib,$RANLIB,$RANLIB,false) # check installer: AC_CHECK_PROG(ac_prog_install,install,install,false) # Output of: cat `find . -name "*.[c]"` | grep "^#include <.*>$" | sort | uniq #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include # help2man utility: AC_MSG_CHECKING([help2man]) if help2man --version >/dev/null 2>&1 ; then AC_MSG_RESULT([help2man]) ac_cv_help2man="yes" HELP2MAN=help2man else AC_MSG_RESULT([no]) ac_cv_help2man="no" HELP2MAN=true fi AC_MSG_CHECKING([for long string extension]) tmpdir=`mktemp -d /tmp/fitsh.XXXXXX` echo 'char * somestring = __extension__ "QQRIQ";' > $tmpdir/test.c if $CC -c $tmpdir/test.c -o $tmpdir/test.o >/dev/null 2>&1 ; then AC_MSG_RESULT([yes]) ac_cv_gcc_extension="yes" else AC_MSG_RESULT([no]) ac_cv_gcc_extension="no" fi rm -f -r $tmpdir if test "x$ac_cv_gcc_extension" = "xno" ; then CFLAGS="${CFLAGS} -DHAVE_NO_CC_EXTENSION" fi # check used headers: AC_CHECK_HEADERS(ctype.h) AC_CHECK_HEADERS(dlfcn.h) AC_CHECK_HEADERS(fcntl.h) AC_CHECK_HEADERS(fnmatch.h) AC_CHECK_HEADERS(math.h) AC_CHECK_HEADERS(time.h) AC_CHECK_HEADERS(errno.h) AC_CHECK_HEADERS(unistd.h) AC_CHECK_HEADERS(signal.h) AC_CHECK_HEADERS(sys/time.h) AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/types.h) AC_CHECK_HEADERS(sys/stat.h) AC_CHECK_HEADERS(sys/mman.h) # Some OS-dependent functions: AC_CHECK_LIB(c,fnmatch) # dynamic library management/handling: AC_CHECK_LIB(dl,dlopen) AC_CHECK_LIB(dl,dlsym) AC_CHECK_LIB(dl,dlclose) ax_cflags_gcc_no_overlength_strings=no AX_CFLAGS_GCC_OPTION(-Wno-overlength-strings,[],[ax_cflags_gcc_no_overlength_strings=yes]) if test $cflags_default == yes && test $ax_cflags_gcc_no_overlength_strings == yes ; then CFLAGS="$CFLAGS -Wno-overlength-strings" fi ax_cflags_gcc_no_long_long=no AX_CFLAGS_GCC_OPTION(-Wno-long-long,[],[ax_cflags_gcc_no_long_long=yes]) if test $cflags_default == yes && test $ax_cflags_gcc_no_long_long == yes ; then CFLAGS="$CFLAGS -Wno-long-long" fi ax_cflags_gcc_no_unused_result=no AX_CFLAGS_GCC_OPTION(-Wno-unused-result,[],[ax_cflags_gcc_no_unused_result=yes]) if test $cflags_default == yes && test $ax_cflags_gcc_no_unused_result == yes ; then CFLAGS="$CFLAGS -Wno-unused-result" fi if test "x$ac_cv_header_fnmatch_h" != "xyes" || \ test "x$ac_cv_lib_c_fnmatch" != "xyes" ; then CFLAGS="${CFLAGS} -DHAVE_NO_FNMATCH_H" fi # some additional functions: # basic math functions: AC_CHECK_LIB(m,sin) AC_CHECK_LIB(m,cos) AC_CHECK_LIB(m,tan) AC_CHECK_LIB(m,asin) AC_CHECK_LIB(m,acos) AC_CHECK_LIB(m,atan) AC_CHECK_LIB(m,atan2) AC_CHECK_LIB(m,sqrt) AC_CHECK_LIB(m,log) AC_CHECK_LIB(m,exp) AC_CHECK_LIB(m,log10) AC_CHECK_LIB(m,exp10) AC_CHECK_LIB(m,pow) AC_CHECK_LIB(m,floor) AC_CHECK_LIB(m,fmod) AC_CHECK_LIB(m,finite) AC_CHECK_LIB(m,isnan) AC_CHECK_LIB(m,isinf) # Debian archiver: AC_MSG_CHECKING([for a debian archiver]) if dpkg-deb --version >/dev/null 2>&1 ; then AC_MSG_RESULT([dpkg-deb]) ac_cv_debian_archiver="yes" DPKG_DEB=dpkg-deb else AC_MSG_RESULT([no]) ac_cv_debian_archiver="no" DPKG_DEB=false fi # Groff: AC_MSG_CHECKING([for a roff formatter]) if groff --version >/dev/null 2>&1 ; then AC_MSG_RESULT([groff]) ac_cv_roff_groff="yes" ROFF=groff else AC_MSG_RESULT([no]) ac_cv_roff_groff="no" ROFF=false fi AC_CHECK_PROG(ac_prog_man,man,man,false) AC_CHECK_PROG(ac_prog_dvips,dvips,dvips,false) AC_CHECK_PROG(ac_prog_gzip,gzip,gzip,false) # Check paper size: AC_MSG_CHECKING([papersize]) if test -x /usr/bin/paperconf ; then PAPERSIZE=`/usr/bin/paperconf` PAPER_WIDTH=`/usr/bin/paperconf -w` PAPER_HEIGHT=`/usr/bin/paperconf -h` elif test -f /etc/papersize ; then PAPERSIZE=`grep -v "^\#" /etc/papersize | head -1` PAPER_WIDTH=0 PAPER_HEIGHT=0 else PAPERSIZE=letter PAPER_WIDTH=612 PAPER_HEIGHT=792 fi AC_MSG_RESULT([$PAPERSIZE: ${PAPER_WIDTH}x${PAPER_HEIGHT}]) ARCH=`uname -m` AC_MSG_CHECKING([dynamic library extensions (HOST=$HOST)]) if test `uname` == Darwin; then OSX_VERSION=`sw_vers -productVersion` DLEXT=dylib DLSWC="-dylib -arch $ARCH -macosx_version_min $OSX_VERSION" DLDYN=-dynamic DLLIB=-ldl AC_MSG_RESULT([dylib]) AC_MSG_NOTICE([OSX linker flags: $DLSWC]) elif test "$HOST" == win32; then DLEXT= DLSWC= DLDYN= DLLIB= AC_MSG_RESULT([not supported]) elif test "$HOST" == win64; then DLEXT= DLSWC= DLDYN= DLLIB= AC_MSG_RESULT([not supported]) elif test `uname` == NetBSD; then DLEXT=so DLSWC=-shared DLDYN=-rdynamic DLLIB= AC_MSG_RESULT([so]) else DLEXT=so DLSWC=-shared DLDYN=-rdynamic DLLIB=-ldl AC_MSG_RESULT([so]) fi DEB_ARCH=`uname -m | sed -e 's/x86_64/amd64/' -e 's/i486/i386/' -e 's/i586/i386/' -e 's/i686/i386/'` DEB_VERSION=$PACKAGE_VERSION FITSH_VERSION=$PACKAGE_VERSION FITSH_RELEASE=$RELEASE_DATE # Final notices: AC_MSG_NOTICE([generic: using CFLAGS: ${CFLAGS}]) AC_MSG_NOTICE([generic: using Debian architecture identifier: ${DEB_ARCH}]) AC_MSG_NOTICE([`lfit`: may use dynamic extensions: $dynamic_extensions]) # Substitution for binary object archiver and linker: AC_SUBST(AR, ${ac_prog_ar}) AC_SUBST(LD, ${ac_prog_ld}) AC_SUBST(RANLIB, ${ac_prog_ranlib}) AC_SUBST(INSTALL, ${ac_prog_install}) # Substitution for dynamic loading and additional optional supported methods: AC_SUBST(DLEXT, ${DLEXT}) AC_SUBST(DLSWC, ${DLSWC}) AC_SUBST(DLDYN, ${DLDYN}) AC_SUBST(DLLIB, ${DLLIB}) # Substitution for documentation and distribution management: AC_SUBST(DEB_VERSION, ${DEB_VERSION}) AC_SUBST(DEB_ARCH, ${DEB_ARCH}) AC_SUBST(DPKG_DEB, ${DPKG_DEB}) AC_SUBST(HELP2MAN, ${HELP2MAN}) AC_SUBST(ROFF, ${ROFF}) AC_SUBST(GZIP, ${ac_prog_gzip}) AC_SUBST(MAN, ${ac_prog_man}) AC_SUBST(DVIPS, ${ac_prog_dvips}) AC_SUBST(PAPERSIZE, ${PAPERSIZE}) AC_SUBST(PAPER_WIDTH, ${PAPER_WIDTH}) AC_SUBST(PAPER_HEIGHT, ${PAPER_HEIGHT}) # Substitution for the config.h header: AC_SUBST(FITSH_VERSION,${FITSH_VERSION}) AC_SUBST(FITSH_RELEASE,${FITSH_RELEASE}) ac_output_list="Makefile config.h libastro/Makefile libfits/Makefile librandom/Makefile libpsn/Makefile src/Makefile src/index/Makefile src/io/Makefile src/link/Makefile src/math/Makefile src/math/dft/Makefile src/math/elliptic/Makefile src/math/elliptic/Makefile src/math/expint/Makefile src/math/fit/Makefile src/math/intersec/Makefile src/math/spline/Makefile src/psn/Makefile doc/Makefile doc/examples/Makefile doc/examples/firandom/Makefile" AC_OUTPUT([${ac_output_list}]) fitsh-0.9.2/src/0000755000175000017500000000000012772016355012052 5ustar apalapalfitsh-0.9.2/src/statistics.h0000644000175000017500000000127410667340126014416 0ustar apalapal/*****************************************************************************/ /* statistics.h */ /*****************************************************************************/ #ifndef __STATISTICS_H_INCLUDED #define __STATISTICS_H_INCLUDED 1 /*****************************************************************************/ /* median(): Sorts the array 'data' of 'n' real values into ascending order and returns the median of the dataset. */ double median(double *data,int n); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/tensor.h0000644000175000017500000000341010667340124013526 0ustar apalapal/*****************************************************************************/ /* tensor.h */ /*****************************************************************************/ #ifndef __TENSOR_H_INCLUDED #define __TENSOR_H_INCLUDED 1 /* tensor_alloc_arr(): Allocates memory for a tensor with rank 'rank', the number of the elements in each dimension have to be specified in the elements of 'dims' ('rank' integers). If the allocation is successful, the function returns the pointer pointing to the newly allocated tensor, otherwise (or if 'rank'<=0) it returns NULL. If a tensor of a given 'type' wants to be allocated, set 'typesize' to sizeof('type') and after the call, recast the pointer returned to ('type' **...**), where the indirection-level (the number of the asterices) is always 'rank'. */ void * tensor_allor_arr(int typesize,int rank,int *dims); /* tensor_alloc(): Does the same what tensor_alloc_arr() does, except that the number of elements in each dimension should be specified as integers after the argument 'rank' (also, 'rank' integers). */ void * tensor_alloc(int typesize,int rank,...); /* tensor_free(): Releases the tensor 'tensor' allocated with tensor_alloc[_arg](). In the current implementation, it calls directly free(), however, it might be changed in the further versions. Currently, this function does always return zero. */ int tensor_free(void *tensor); #define tensor_alloc_1d(type,a) tensor_alloc(sizeof(type),1,a) #define tensor_alloc_2d(type,a,b) tensor_alloc(sizeof(type),2,a,b) #define tensor_alloc_3d(type,a,b,c) tensor_alloc(sizeof(type),3,a,b,c) #define tensor_alloc_4d(type,a,b,c,d) tensor_alloc(sizeof(type),4,a,b,c,d) #endif fitsh-0.9.2/src/lfit-info.c0000644000175000017500000010324512771247605014115 0ustar apalapal/*****************************************************************************/ /* lfit-info.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Symbolic fitting & arithmetic evaluating utility. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 1996, 2002, 2004-2005, 2006, 2007-2008, 2009; */ /* Pal, A. (apal@szofi.net) */ /*****************************************************************************/ #include #include #include #include "fitsh.h" #include "longhelp.h" #include #include "lfit-info.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ int fprint_lfit_usage(FILE *fw) { fprintf(fw, "Usage:\tlfit [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[--examples] [--function-list]\n" "\t[-V|--verbose] [--quiet] [-o|--output ] \n"); fprintf(fw, "Common parameters and arguments for fitting and/or regression analysis:\n" "\t-v [[:]=[:][[]:[]]] [,...]\n" "\t-g =[,...]\n" "\t[-F|--format =[,...]]\n" "\t[-C|--correlation-format \n" "\t[-q|--difference =[,...]]\n" "\t[-t|--constraint =[,...]]\n" "\t[-x|--define|--macro (v1,v2,...)= [-x ...]]\n"); fprintf(fw, "Parameters for simple fitting (single data block):\n" "\t[|-] -c -f [=]\n" "\t[-y ] [-e |-w ]\n"); fprintf(fw, "Parameters for fitting more than one data blocks:\n" "\t-i |- -c -f [=]\n" "\t[-y ] [-e |-w ]\n" "\t-i |- -c -f [=]\n" "\t[-y ] [-e |-w ]\n" "\t[...]\n"); fprintf(fw, "Fit methods:\tderivatives & linearity\n" "\t[-L|--clls]\tyes\tyes\t" "# Classic linear least squares\n" "\t[-N|--nllm]\tyes\tno\t" "# Nonlinear Levenberg-Marquardt\n" "\t[-E|--emce]\topt.\topt.\t" "# Refitting to synthetic data sets\n" "\t[-M|--mcmc]\tno\tno\t" "# Markov Chain Monte-Carlo\n" "\t[-K|--mchi]\tno\tno\t" "# Grid mapping of Chi^2\n" "\t[-X|--xmmc]\tyes\tno\t" "# Extended Markov Chain Monte-Carlo\n" "\t[-U|--lmnd]\tno\tno\t" "# Levenberg-Marquardt + num. derivatives\n" "\t[-D|--dhsx]\topt.\tno\t" "# Downhill simplex\n" "\t[-A|--fima]\tyes\tno\t" "# Fisher Information Matrix Analysis\n"); fprintf(fw, "Fine-tune parameters [-P|--params]:\n" "\t-N -P\t[default],[lambda=],[multiply=],[iterations=]\n" "\t-U -P\t[default],[lambda=],[multiply=],[iterations=] -q <...>\n" "\t-D -P\t[default],[fisher]\n" "\t-E -P\t[default],[skip],{linear|nonlinear|lmnd|dhsx[fisher]|mc}\n" "\t-M -P\t[default],[[non]accepted],[gibbs]\n" "\t-X -P\t[default],[[non]accepted],[skip],\n" "\t\t[adaptive],[iterations=],[window=]\n" "\t-A -P\t[default],[[no]orig],[[no]errors],[[no]corr],[mc|montecarlo]\n" "\t[-U|-E [-q <...>]]\n"); fprintf(fw, "\t[-i|--{emce|mcmc|xmmc|fima}-iterations ] [-s|--seed |-1]\n" "\t[--errors|--error-line|--error-columns] [--residual]\n" "\t[--perturbations =[,=[,...]]]\n" "\t[-r -n [--weighted-sigma]]\n" "\t[-k|--separate [@],[!],...]\n"); #ifdef LFIT_ENABLE_DYNAMIC_EXTENSIONS fprintf(fw, "Dynamically loaded external libraries and functions:\n" "\t[-d|--dynamic :[,,...] [-d <...>]]\n"); #endif fprintf(fw, "General output specification:\n" "\t[-o|--output ]\n"); fprintf(fw, "More outputs:\n" "\t[-u ] [-j ]\n" "\t[-a [--delta|--delta-comment]]\n" "\t[-p ] [-l ]\n"); return(0); } longhelp_entry lfit_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "--functions, --list-functions, --function-list", "Lists the available arithmetic operations and built-in functions " "supported by the program." }, { "--examples", "Prints some very basic examples for the program invocation." }, { "Common options for regression analysis:", NULL }, { "-v, --variable, --variables ", "Comma-separated list of regression variables. In case of non-linear " "regression analysis, all of these fit variables are expected to have " "some initial values (specified as =), otherwise the " "initial values are set to be zero. Note that in the case of some of " "the regression/analysis methods, additional parameters should be " "assigned to these fit/regression variables. See the section " "\"Regression analysis methods\" for additional details." }, { "-c, --column, --columns [:],...", __extension__ "Comma-separated list of independet variable names as read from the " "subsequent columns of the primary input data file. If the independent " "variables are not in sequential order in the input file, the optional " "column indices should be defined for each variable, by separating the " "column index with a colon after the name of the variable. " "In the case of multiple input files and data blocks, the user " "should assign the individual independent variables and the " "respective column names and definitions for each file " "(see later, Sec. \"Multiple data blocks\")." }, { "-f, --function ", __extension__ "Model function of the analysis in a symbolic form. This expression " "for the model function " "should contain built-in arithmetic operators, built-in functions, " "user-defined macros (see -x, --define) or functions provided by the " "dynamically loaded external modules (see -d, --dynamic). The model " "function can depend on both the fit/regression variables " "(see -v, --variables) and the independent variables read from the " "input file (see -c, --columns). In the case of multiple input files " "and data blocks, the user should assign the respective model functions " "for each data block (see later). Note that some of the analysis methods " "expects the model function to be either differentiable or linear in " "the fit/regression variables. See \"Regression analysis methods\" later " "on about more details." }, { "-y, --dependent ", __extension__ "The dependent variable of the regression analysis, in a form of an " "arithmetic expression. This expression for the dependent variable " "can depend only on the variables read from the input file " "(see -c, --columns). In the case of multiple input files " "and data blocks, the user should assign the respective dependent " "expressions for each data block (see later)." }, { "-o, --output ", "Name of the output file into which the fit results (the values for the " "fit/regression variables) are written." }, { "Common options for function evaluation:", NULL }, { "-f, --function [...]", "List of functions to be evaluated. More expressions can be specified by " "either separating the subsequent expressions by a comma or by " "specifying more -f, --function options in the command line." }, { "Note that the two basic modes of `lfit` are distinguished only by the " "presence or the absence of the -y, --dependent command line argument. " "In other words, there isn't any explicit command line argument which " "specify the mode of `lfit`. If the -y, --dependent command line argument " "is omitted, `lfit` runs in function evaluation mode, otherwise " "the program runs in regression analysis mode.", NULL }, { "",NULL }, { "-o, --output ", "Name of the output file in which the results of the function " "evaluation are written." }, { "Regression analysis methods:", NULL }, { "-L, --clls, --linear", __extension__ "The default mode of `lfit`, the classical linear least squares (CLLS) method. " "The model functions specified after -f, --function are expected to be " "both differentiable and linear with respect to the fit/regression " "variables. Otherwise, `lfit` detects the non-differentiable and " "non-linear property of the model function(s) and refuses the analysis. " "In this case, other types of regression analysis methods can be applied " "depending our needs, for instance the Levenberg-Marquardtalgorithm " "(NLLM, see -N, --nllm) or the downhill simplex minimization " "(DHSX, see -D, --dhsx)." }, { "-N, --nllm, --nonlinear", __extension__ "This option implies a regression involving the nonlinear " "Levenberg-Marquardt (NLLM) minimization " "algorithm. The model function(s) specified after -f, --function are " "expected to be differentiable with respect to the fit/regression " "variables. Otherwise, `lfit` detects the non-differentiable property " "and refuses the analysis. There some fine-tune parameters of the " "Levenberg-Marquardt algorithm, see also the secion " "\"Fine-tuning of regression analysis methods\" for more details how " "these additional regression parameters can be set. Note that all of " "the fit/regression variables should have a proper initial value, " "defined in the command line argument -v, --variable (see also there)." } , { "-U, --lmnd", __extension__ "Levenberg-Marquardt minimization with numerical partial " "derivatives (LMND). Same as the NLLM method, with the exception of " "that the partial " "derivatives of the model function(s) are calculated numerically. " "Therefore, the model function(s) may contain functions of which " "partial derivatives are not known in an analytic form. " "The differences used in the computations of the partial derivatives " "should be declared by the user, see also the command line option " "-q, --differences. " }, { "-D, --dhsx, --downhill", __extension__ "This option implies a regression involving the nonlinear " "downhill simplex (DHSX) minimization algorithm. " "The user should specify the proper inital values " "and their uncertainties as =:, unless " "the \"fisher\" option is passed to the -P, --parameters command line " "argument (see later in the section \"Fine-tuning of regression " "analysis methods\"). In the first case, the initial size of the " "simplex is based on the uncertainties provided by the user while " "in the second case, the initial simplex is derived from the " "eigenvalues and eigenvectors of the Fisher covariance matrix. " "Note that the model functions must be differentiable in the " "latter case. " }, { "-M, --mcmc", __extension__ "This option implies the method of Markov Chain Monte-Carlo (MCMC). " "The model function(s) can be arbitrary in the point of " "differentiability. However, each of the fit/regression variables " "must have an initial assumption for their uncertainties which must " "be specified via the command line argument -v, --variable. " "The user should specify the proper inital values " "and uncertainties of these as =:. " "In the actual implementation of `lfit`, each variable has an " "uncorrelated Gaussian a priori distribution with the specified " "uncertainty. The MCMC algorithm has some fine-tune parameters, " "see the section \"Fine-tuning of regression analysis methods\" " "for more details." }, { "-K, --mchi, --chi2", __extension__ "With this option one can perform a \"brute force\" Chi^2 minimization " "by evaluating the value of the merit function of Chi^2 on a grid of " "the fit/regression variables. In this case the grid size and resolution " "must be specified in a specific form " "after the -v, --variable command line argument. Namely each of the " "fit/regression variables intended to be varied on a grid must " "have a format of =[::] while the other ones " "specified as = are kept fixed. The output of this " "analysis will be a series of lines with N+1 columns, where the " "values of fit/regression variables are followed by the value " "of the merit function. Note that all of the declared fit/regression " "variables are written to the output, including the ones which are fixed " "(therefore the output is somewhat redundant)." }, { "-E, --emce", __extension__ "This option implies the method of \"refitting to synthetic data sets\", " "or \"error Monte-Carlo estimation\" (EMCE). This method must have a " "primarily assigned minimization algorithm (that can be any of the " "CLLS, NLLM or DHSX methods). First, the program searches the best fit " "values for the fit/regression variables involving the assigned primary " "minimization algorithm and reports these best fit variables. " "Then, additional synthetic data sets are generated around this set " "of best fit variables and the minimization is repeated involving the same " "primary method. The synthetic data sets are generated independently " "for each input data block, taking into account the fit residuals. " "The noise added to the best fit data is generated from the power " "spectrum of the residuals." }, { "-X, --xmmc", __extension__ "This option implies an improved/extended version of the Markov Chain " "Monte-Carlo analysis (XMMC). The major differences between the classic MCMC " "and XMMC methods are the following. 1/ The transition distribution " "is derived from the Fisher covariance matrix. 2/ The program performs " "an initial minimization of the merit function involving the method " "of downhill simplex. 3/ Various sanity checks are performed in order " "to verify the convergence of the Markov chains (including the " "comparison of the actual and theoretical transition probabilities, " "the computation of the autocorrelation lengths of each " "fit/regression variable series and the comparison of the statistical " "and Fisher covariance). " }, { "-A, --fima", __extension__ "Fisher information matrix analysis (FIMA). With this analysis method " "one can estimate the uncertainties and correlations of the " "fit/regression variables involving the method of Fisher matrix " "analysis. This method does not minimize the merit functions by " "adjusting the fit/regression variables, instead, the initial values " "(specified after the -v, --variables option) are expected to be the " "\"best fit\" ones." }, { "Fine-tuning of regression analysis methods:", NULL }, { "-e, --error ", "Expression for the uncertainties. Note that zero or negative " "uncertainty is equivalent to zero weight, i.e. input lines with zero " "or negative errors are discarded from the fit." }, { "-w, --weight ", "Expression for the weights. The weight is simply the reciprocal of " "the uncertainty. The default error/uncertainty (and therefore " "the weight) is unity. Note that most of the analysis/regression " "methods are rather sensitive to the uncertainties since the merit " "function also depends on these." }, { "-P, --parameters ", "This option is followed by a set of optional fine-tune parameters, " "that is different for each primary regression analysis method:" }, { "default, defaults", "Use the default fine-tune parameters for the given regression method." }, { "clls, linear", "Use the classic linear least squares method as the primary minimization " "algorithm of the EMCE method. Like in the case of the CLLS regression " "analysis (see -L, --clls), the model function(s) must be both differentiable and linear " "with respect to the fit/regression variables. " }, { "nllm, nonlinear", "Use the non-linear Levenberg-Marquardt minimization algorithm as " "the primary minimization algorithm of the EMCE method. Like in the case of the NLLM regression " "analysis (see -N, --nllm), the model function(s) must be differentiable " "with respect to the fit/regression variables. " }, { "lmnd", "Use the non-linear Levenberg-Marquardt minimization algorithm as " "the primary minimization algorithm of the EMCE method. " "Like in the case of -U, --lmnd regression method, the parametric " "derivatives of the model function(s) are calculated by a " "numerical approximation (see also -U, --lmnd and -q, --differences for " "additional details)." }, { "dhsx, downhill", "Use the downhill simplex (DHSX) minimization as the primary " "minimization algorithm of the EMCE method. Unless the additional " "'fisher' option is specified directly, like in the default case of " "the DHSX regression method, the user should specify the uncertainties " "of the fit/regression variables that are used as an initial size " "of the simplex." }, { "mc, montecarlo", "Use a primitive Monte-Carlo diffusion minimization technique as the " "primary minimization algorithm of the EMCE method. The user should " "specify the uncertainties of the fit/regression variables which are " "then used to generate the Monte-Carlo transitions. This primary " "minimization technique is rather nasty (very slow), " "so its usage is not recommended. " }, { "fisher", __extension__ "In the case of the DHSX regression method or in the case of the EMCE " "method when the primary minimization is the downhill simplex algorithm, " "the initial size of the simplex is derived from the Fisher covariance " "approximation evaluated at the point represented by the initial " "values of the fit/regression variables. Since the derivation of the " "Fisher covariance requires the knowledge of the partial derivatives " "of the model function(s) with respect to the fit/regression variables, " "the(se) model function(s) must be differentiable. On the other hand, " "the user do not have to specify the initial uncertainties after the " "-v, --variables option since these uncertainties derived automatically " "from the Fisher covariance." }, { "skip", "In the case of EMCE and XMMC method, the initial minimization " "is skipped. " }, { "lambda=", "Initial value for the \"lambda\" parameter of the Levenberg-Marquardt " "algorithm. " }, { "multiply=", "Value of the \"lambda multiplicator\" parameter of the " "Levenberg-Marquardt algorithm. " }, { "iterations=", "Number of iterations during the Levenberg-Marquardt algorithm. " }, { "accepted", "Count the accepted transitions in the MCMC and XMMC methods (default)." }, { "nonaccepted", "Count the total (accepted plus non-accepted) transitions in the MCMC " "and XMMC methods." }, { "gibbs", "Use the Gibbs sampler in the MCMC method. " }, { "adaptive", "Use the adaptive XMMC algorithm (i.e. the Fisher covariance is " "re-computed after each accepted transition). " }, { "window=", "Window size for calculating the autocorrelation lengths for the " "Markov chains (these autocorrelation lengths are reported only " "in the case of XMMC method). The default value is 20, which is " "fine in the most cases since the typical autocorrelation lengths " "are between 1 and 2 for nice convergent chains." }, { "-q, --difference =[,...]", "The analysis method of LMND (Levenberg-Marquardt minimization using " "numerical derivatives, see -U, --lmnd) requires the differences that " "are used during the computations of the partial derivatives of the " "model function(s). With this option, one can specify these differences." }, { "-k, --separate [,...]", __extension__ "In the case of non-linear regression methods (for instance, DHSX or XMMC) " "the fit/regression variables in which the model functions are linear " "can be separated from the nonlinear part and therefore make the " "minimization process more robust and reliable. Since the " "set of variables in which the model functions are linear is " "ambiguous, the user should explicitly specify this supposedly " "linear subset of regression variables. " "(For instance, the model function \"a*b*x+a*cos(x)+b*sin(x)+c*x^2\" " "is linear in both \"(a,c)\" and \"(b,c)\" parameter vectors but it " "is non-linear in \"(a,b,c)\".) " "The program checks whether the specified subset of " "regression variables is a linear subset and reports " "a warning if not. " "Note that the subset of separated linear variables (defined here) " "and the subset of the fit/regression variables affected by " "linear constraints (see also section \"Constraints\") " "must be disjoint." }, { "--perturbations , --perturbations =[,...]", "Additional white noise to be added to each EMCE synthetic data sets. " "Each data block (referred here by the approprate data block keys, " "see also section \"Multiple data blocks\") may have different white " "noise levels. If there is only one data block, this command line " "argument is followed only by a single number specifying the " "white noise level." }, { "Additional parameters for Monte-Carlo analysis:", NULL }, { "-s, --seed ", __extension__ "Seed for the random number generator. By default this seed is 0, thus " "all of the Monte-Carlo regression analyses (EMCE, MCMC, XMMC " "and the optional generator for the FIMA method) generate " "reproducible parameter distributions. A positive value after this " "option yields alternative random seeds while all negative values " "result in an automatic random seed (derived from various available " "sources, such as /dev/[u]random, system time, hardware MAC address " "and so), therefore distributions generated involving this kind of " "automatic random seed are not reproducible." }, { "-i, --[mcmc,emce,xmmc,fima]-iterations ", "The actual number of Monte-Carlo iterations for the MCMC, EMCE, " "XMMC methods. Additionally, the FIMA method is capable to generate " "a mock Gaussian distribution of the parameter with the same covariance " "as derived by the Fisher analysis. The number of points in this mock " "distribution is also specified by this command line option. "}, { "Clipping outlier data points:", NULL }, { "-r, --sigma, --rejection-level ", "Rejection level in the units of standard deviations." }, { "-n, --iterations ", "Maximum number of iterations in the outlier clipping cycles. " "The actual number of outlier points can be traced by increasing the " "verbosity of the program (see -V, --verbose)." }, { "--[no-]weighted-sigma", "During the derivation of the standard deviation, the contribution of " "the data points data points can be weighted by the respective " "weights/error bars (see also -w, --weight or -e, --error in the " "section \"Fine-tuning of regression analysis methods\"). If no " "weights/error bars are associated to the data points (i.e. both " "-w, --weight or -e, --error options are omitted), this option will have " "no practical effect." }, { "Note that in the actual version of `lfit`, only the CLLS, NLLM and LMND " "regression methods support the above discussed way of " "outlier clipping.", NULL }, { "", NULL }, { "Multiple data blocks:", NULL }, { "-i ", "Input file name for the data block named as ." }, { "-c [:],...", "Column definitions (see also -c, --columns) for the given data " "block named as ." }, { "-f ", "Expression for the model function assigned to the data block named as ." }, { "-y ", "Expression of the dependent variable for the data block named as ." }, { "-e ", "Expression of the uncertainties for the data block named as ." }, { "-w ", "Expression of the weights for the data block named as . Note that " "like in the case of -e, --errors and -w, --weights, only one of the " "-e, -w arguments should be specified." }, { "Constraints:", NULL }, { "-t, --constraint, --constraints {=<>}[,...]", __extension__ "List of fit and domain constraints between the regression variables. " "Each fit constraint expression must be linear in the fit/regression variables. " "The program checks the linearity of the fit constraints and reports an " "error if any of the constraints are non-linear. " " A domain constraint can be any " "expression involving arbitrary binary arithmetic relation (such as " "strict greater than: '>', strict less than: '<', " "greater or equal to: '>=' and less or requal to: '<='). " "Constraints can be " "specified either by a comma-separated list after a single command " "line argument of -t, --constraints or by multiple of these " "command line arguments. " }, { "-v, --variable :=", "Another form of specifying constraints. The variable specifications " "after -v, --variable can also be used to define constraints by writing " "\":=\" instead of \"=\" between the variable name and initial value. " "Thus, -v := is equivalent to -v = " "-t =." }, { "User-defined functions:", NULL }, { "-x, --define, --macro ()=", __extension__ "With this option, the user can define additional functions " "(also called macros) on the top of the built-in functions and operators, " "dynamically loadaded functions and previously defined macros. " "Note that each such user-defined function must be stand-alone, i.e. " "external variables (such as fit/regression variables and independent " "variables) cannot be part of the definition expression, only the " "parameters of these functions." }, { "Dynamically loaded extensions and functions:", NULL }, { "-d, --dynamic :[,...]", __extension__ "Load the dynamically linked library (shared object) named " "and import the global `lfit`-compatible set of functions defined " "in the arrays specified after the name of the library. The arrays " "must have to be declared with the type of 'lfitfunction', as it is " "defined in the file \"lfit.h\". Each record in this array contains " "information about a certain imported function, namely " "the actual name of this function, flags specifying whether the " "function is differentiable and/or linear in its regression parameters, " "the number of regression variables and independent variables " "and the actual C subroutine that implements the evaulation of the " "function (and the optional computation of the partial derivatives). " "The module 'linear.c' and 'linear.so' provides a simple example " "that implements the \"line(a,b,x)=a*x+b\" function. " "This example function has " "two regression variables (\"a\" and \"b\") and one independent " "variable (\"x\") and the function itself is linear in the regression " "variables." }, { "More on outputs:", NULL }, { "-z, --columns-output ", __extension__ "Column indices where the results are written in evaluation mode. " "If this option is omitted, the results of the function evaluation " "are written sequentally. Otherwise, the input file is written to " "the output and the appropriate columns (specified here) are replaced " "by the respective results of the function evaluation. Thus, although " "the default column order is sequential, there is a significant " "difference between omitting this option and specifying \"-z 1,2,...,N\". " "In the first case, the output file contains only the results of the " "function evaluations, while in the latter case, the first N columns " "of the original file are replaced with the results. " }, { "--errors, --error-line, --error-columns", "Print the uncertainties of the fit/regression variables." }, { "-F, --format =[,...]", "Format of the output in printf-style for each fit/regression variable" "(see printf(3)). The default " "format is %12.6g (6 signifiant figures)." }, { "-F, --format [,...]", "Format of the output in evaluation mode. The default " "format is %12.6g (6 signifiant figures)." }, { "-C, --correlation-format ", "Format of the correlation matrix elements. The default format " "is %6.3f (3 significant figures)." }, { "-g, --derived-variable[s] =[,...]", "Some of the regression and analysis methods are capable to " "compute the uncertainties and correlations for derived regression " "variables. These additional (and therefore not independent) " "variables can be defined with this command line option. " "In the definition expression one should use only the fit/regression " "variables (as defined by the -v, --variables command line argument). " "The output format of these variables can also be specified by the " "-F, --format command line argument." }, { "-u, --output-fitted ", "Neme of an output file into which those lines of the input are " "written that were involved in the final regression. This option " "is useful in the case of outlier clipping in order to see what " "was the actual subset of input data that was used in the fit " "(see also the -n, --iterations and -r, --sigma options)." }, { "-j, --output-rejected ", "Neme of an output file into which those lines of the input are " "written that were rejected from the final regression. This option " "is useful in the case of outlier clipping in order to see what " "was the actual subset of input data where the dependent variable " "represented outlier points " "(see also the -n, --iterations and -r, --sigma options)." }, { "-a, --output-all ", "File containing the lines of the input file that were involved " "in the complete regression analysis. This file is simply the " "original file, only the commented and empty lines are omitted. " }, { "-p, --output-expression ", "In this file the model function is written in which the " "fit/regression variables are replaced by their best-fit values. " }, { "-l, --output-variables ", "List of the names and values of the fit/regression variables in the " "same format as used after the -v, --variables command line argument. " "The content of this file can therefore be passed to subsequent " "invocations of `lfit`." }, { "--delta", "Write the individual differences between the independent " "variables and the evaluated best fit model function values for each " "line in the output files specified by the -u, --output-fitted, " "-j, --output-rejected and -a, --output-all command line options." }, { "--delta-comment", "Same as --delta, but the differences are written as a comment " "(i.e. separated by a '##' from the original input lines)." }, { "--residual", "Write the final fit residual to the output file (after the list of " "the best-fit values for the fit/regression variables)." }, { NULL, NULL } }; int fprint_lfit_long_help(FILE *fw,int is_wiki) { char *synopsis= "lfit [method of analysis] [options] [-o, --output ]"; char *description= __extension__ "The program `lfit` is a standalone command line driven tool designed for " "both interactive and batch processed data analysis and regression. " "In principle, the program may run in two modes. First, `lfit` supports " "numerous regression analysis methods that can be used to search for " "\"best fit\" parameters of model functions in order to model the input " "data (which are read from one or more input files in tabulated form). " "Second, `lfit` is capable to read input data and performs various " "arithmetic operations as it is specified by the user. Basically this second " "mode is used to evaluate the model functions with the parameters presumably " "derived by the actual regression methods (and in order to complete this " "evaluation, only slight changes are needed in the command line invocation " "arguments)."; fprint_generic_long_help(fw,is_wiki,lfit_long_help,synopsis,description); return(0); } int fprint_lfit_examples(FILE *fw) { fprintf(fw, "Examples:\n" "* linear regression in 1+1 dim:\n" "\tlfit -v a,b -c x,y -f \"a*x+b\" -y y\n" "* linear regression in 1+1 dim, taking into account errors (from 3d column):\n" "\tlfit -v a,b -c x,y,yerr -f \"a*x+b\" -y y -e yerr\n" "* fit a circle in 2 dim (find the center and radius of a circle which \n" " fits well to the points given in the first two columns of the input):\n" "\tlfit -v u,v,uvr -c x,y -f \"2*x*u+2*y*v-uvr\" -y \"x*x+y*y\"\n" " The center of the circle is (u,v) and the raduis is r=sqrt(u*u+v*v-uvr).\n"); fprintf(fw, "Some notes: \n" " - Avoid to put spaces or any nasty characters (such as wildchards: *, ?,\n" " backslash, brackets -- which are pre-interpreted by the shell) directly\n" " in the arguments of -v, -c, -f, -y and -e|-w. Simply put such arguments\n" " between quotation marks (or escape them), see the examples above.\n" " - If the function 'function' is linear in the variables 'vars' are to be\n" " fitted, the standard linear regression algorithm will be used. Otherwise,\n"); fprintf(fw, " the Levenberg-Marquardt method will be used (with the parameters optionally\n" " defined by the switches -l, -m and -i), if the switch -N is specified in the\n" " command line to force the non-linear method. In this case, the initial\n" " values of the variables 'vars' are important to be defined in the argument\n" " of -v. With the switch -V (--verbose) the evolution of the variables and\n" " the lambda parameter can be traced ('max_iter' lines are written to stderr).\n"); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/wcs.h0000644000175000017500000000301012463215347013010 0ustar apalapal/*****************************************************************************/ /* wcs.h */ /*****************************************************************************/ #ifndef __WCS_H_INCLUDED #define __WCS_H_INCLUDED 1 /*****************************************************************************/ #define M_R2D (180.0/M_PI) #define M_D2R (M_PI/180.0) /*****************************************************************************/ #define WCS_SIN 0 #define WCS_ARC 1 #define WCS_TAN 2 typedef double vector[3]; typedef double matrix[3][3]; typedef struct { double ra0,de0; int type,order; matrix mproj; double zfactor; } wcsinit; typedef struct { wcsinit init; double *pixpoly[2]; double *prjpoly[2]; double crota; double crpix1,crpix2; double cdelt1,cdelt2; } wcsdata; int wcs_get_projection_matrix(double ra0,double de0,matrix mproj); int wcs_get_projected_coords_matrix(matrix mproj, double ra,double de,double *rx,double *ry,double *rz); int wcs_invert_projected_coords_matrix(matrix mproj, double x,double y,double *rra,double *rde); int wcs_project_distort(int type,double *rx,double *ry,double *rz); int wcs_invert_project_distort(int type,double *rx,double *ry,double *rz); int wcs_get_projected_coords(double ra0,double de0, double ra,double de,double *rx,double *ry,double *rz); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/lfit-info.h0000644000175000017500000000127412766066431014121 0ustar apalapal/*****************************************************************************/ /* lfit-info.h */ /*****************************************************************************/ #ifndef __LFIT_INFO_H_INCLUDED #define __LFIT_INFO_H_INCLUDED 1 /*****************************************************************************/ int fprint_lfit_usage(FILE *fw); int fprint_lfit_long_help(FILE *fw,int is_wiki); int fprint_lfit_examples(FILE *fw); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/fbase.c0000644000175000017500000000271011116253527013271 0ustar apalapal/*****************************************************************************/ /* fbase.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2008; Pal, A. */ /*****************************************************************************/ #include #include #include #include #include #include "math/spline/spline.h" #include "fbase.h" /*****************************************************************************/ int fbase_spline(double **fbase,int order,int n) { double *y1,*y2,x; int i,o; y1=(double *)malloc(sizeof(double)*(order+1)); y2=(double *)malloc(sizeof(double)*(order+1)); for ( o=0 ; o<=order ; o++ ) { for ( i=0 ; i<=order ; i++ ) { y1[i]=(i==o?1.0:0.0); } natspline_coeff(y1,order+1,y2); for ( i=0 ; i #include "fitsmask.h" #define OOSQ2PI 0.3989422804014326779 #define OOSQ2 0.7071067811865475244 /*****************************************************************************/ typedef struct { double x,y; double dx,dy; } dpoint; /*****************************************************************************/ int mark_saturated_pixels(fitsimage *img,char **mask,fitsimage *satimg,double param,int method); int join_masks_from_files(char **mask,int sx,int sy,char **inmasklist); int mark_integerlimited_pixels(fitsimage *img,char **mask,int bitpix,int is_corr,int mvlo,int mvhi); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/index/0000755000175000017500000000000012772016355013161 5ustar apalapalfitsh-0.9.2/src/index/multiindex.h0000644000175000017500000000372010667340131015507 0ustar apalapal/*****************************************************************************/ /* multiindex.h */ /*****************************************************************************/ #ifndef __MULTIINDEX_H_INCLUDED #define __MULTIINDEX_H_INCLUDED 1 /*****************************************************************************/ typedef struct { int depth; int value; } nodeindex; typedef struct { nodeindex i; int min; int max; } nodeinterval; /* interval is always [min,max) ! */ typedef struct { int nbit,size; void *param; int *i_pri,*i_sec; int *ind_x; int **ind_xy; } multiindex; /*****************************************************************************/ int get_nbit(int x); int index_quicksort(int *index,int n, int (*compare)(int,int,void *),void *param); int check_if_in_interval(void *arr,int p, int (*compare)(int,double,void *),double *xl,double *xr); int search_index_boundaries(void *arr,int *index,int size, int (*compare)(int,double,void *), double *rx0,int *rleft ,nodeindex *nleft, double *rx1,int *rright,nodeindex *nright); int get_nodeintervals(int ileft,int iright,int size,nodeinterval *nis); int index_subsort(int *index,int (*compare)(int,int,void *), int level,int min,int max,void *arr); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int multiindex_create(void *param,int size, int (*compare_x)(int,int,void *), int (*compare_y)(int,int,void *), multiindex *mi); int multiindex_range_query(multiindex *mi, int (*compare_value_x)(int,double,void *), int (*compare_value_y)(int,double,void *), double xl,double xr,double yl,double yr, int *ret,int maxret); int multiindex_free(multiindex *mi); int multiindex_reset(multiindex *mi); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/index/sort.c0000644000175000017500000000733010667340131014310 0ustar apalapal/*****************************************************************************/ /* sort.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for sorting an indexed array. */ /* (c) 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in sort.h. */ /*****************************************************************************/ #include #include #include "sort.h" /*****************************************************************************/ static int index_qsort_local(int *index,int l,int r, int (*compare)(int,int,void *),void *param) { int i,j,tmp,ch; ch=index[(l+r)/2]; i=l-1,j=r+1; while ( 1 ) { do { i++; } while ( index[i] != ch && compare(index[i],ch,param)<0 ) ; do { j--; } while ( index[j] != ch && compare(index[j],ch,param)>0 ) ; if ( ilo=(low)),(top->hi=(high)),top++)) #define POP(low,high) ((void)(top--,(low=top->lo),(high=top->hi))) int index_qsort(int *index,int n,int (*compare)(int,int,void *),void *param) { int t; if ( n<=0 ) return(0); if ( n>MAX_THRESH ) { stacknode stack[64],*top; int lo=0,hi=n-1,mid,left,right; top=&stack[1]; while ( top>stack ) { mid=lo+((hi-lo)>>1); if ( compare(index[mid],index[lo],param)<0 ) t=index[mid],index[mid]=index[lo],index[lo]=t; if ( compare(index[hi],index[mid],param)<0 ) t=index[hi],index[hi]=index[mid],index[mid]=t; else goto skip_compare; if ( compare(index[mid],index[lo],param)<0 ) t=index[mid],index[mid]=index[lo],index[lo]=t; skip_compare: left=lo+1; right=hi-1; do { while ( compare(index[left],index[mid],param)<0 ) left++; while ( compare(index[mid],index[right],param)<0 ) right--; if ( left hi-left ) { PUSH(lo,right); lo=left; } else { PUSH(left,hi); hi=right; } } } do { int end=n-1; int tmp=0,run,trav; int thresh=(end>MAX_THRESH?MAX_THRESH:end); for ( run=tmp+1 ; run<=thresh ; run++ ) { if ( compare(index[run],index[tmp],param)<0 ) tmp=run; } if ( tmp != 0 ) t=index[0],index[0]=index[tmp],index[tmp]=t; run=1; while ( (run+=1) <= end ) { tmp=run-1; while ( compare(index[run],index[tmp],param)<0 ) tmp--; tmp++; if ( tmp != run ) { trav=run+1; while ( (--trav)>=run ) { int c=index[trav]; int hi,lo; for ( hi=lo=trav ; (lo-=1)>=tmp ; hi=lo ) index[hi]=index[lo]; index[hi]=c; } } } } while(0); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/index/sort.h0000644000175000017500000000226010667340131014312 0ustar apalapal/*****************************************************************************/ /* sort.h */ /*****************************************************************************/ #ifndef __SORT_H_INCLUDED #define __SORT_H_INCLUDED 1 /*****************************************************************************/ /* index_qsort(): Sorts the array 'index' to satisfy the relation compare(index[i],index[i+1],param) <= 0 (for all i=0,... , n-2). The function index_qsort() uses the quick sort algorihm enhanced with insertion sort on shorter blocks of the array. The optional argument 'param' is always passed to the comparison function 'compare' at all invocations. */ int index_qsort(int *index,int n, int (*compare)(int index1,int index2,void *param),void *param); /* index_qsort_old(): Previous implementation. Obsoleted by index_qsort(). */ int index_qsort_old(int *index,int n, int (*compare)(int index1,int index2,void *param),void *param); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/index/Makefile.in0000644000175000017500000000040511657564426015235 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ CFLAGS=@CFLAGS@ all: sort.o multiindex.o .PHONY: all clean sort.o: sort.c sort.h $(CC) $(CFLAGS) -c sort.c multiindex.o: multiindex.c multiindex.h $(CC) $(CFLAGS) -c multiindex.c clean: rm -f *.o fitsh-0.9.2/src/index/multiindex.c0000644000175000017500000001666011021340273015501 0ustar apalapal/*****************************************************************************/ /* multiindex.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for (currently only) 2-dimensional orthogonal range */ /* search. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include "multiindex.h" /*****************************************************************************/ int get_nbit(int x) { int nbit; for ( nbit=0 ; x>0 ; ) { x=x/2; nbit++; } return(nbit); } /*****************************************************************************/ int index_quicksort_rec(int *index,int l,int r, int (*compare)(int,int,void *),void *param) { int i,j,tmp,ch; ch=index[(l+r)/2]; i=l-1,j=r+1; while ( 1 ) { do { i++; } while ( index[i] != ch && compare(index[i],ch,param)<0 ) ; do { j--; } while ( index[j] != ch && compare(index[j],ch,param)>0 ) ; if ( i0 ) { mid=(min+max)/2; index_subsort(index,compare,level-1,min,mid,param); index_subsort(index,compare,level-1,mid,max,param); return(0); } else if ( max>min+1 ) { index_quicksort(index+min,max-min,compare,param); return(0); } else return(0); } /*****************************************************************************/ /* functions related to 1d range searching */ int check_if_in_interval(void *param,int p, int (*compare)(int,double,void *),double *xl,double *xr) { if ( xl != NULL && ! ( 0 <= compare(p,*xl,param) ) ) /* II */ return(0); else if ( xr != NULL && ! ( compare(p,*xr,param)<=0 ) ) /* II */ return(0); else return(1); } int search_index_boundaries(void *param,int *index,int size, int (*compare)(int,double,void *), double *rx0,int *rleft ,nodeindex *nleft, double *rx1,int *rright,nodeindex *nright) { nodeindex n; int min,max,mid,mask; double x0,x1; if ( rleft == NULL || rright == NULL ) return(-1); if ( rx0==NULL ) { *rleft=0; if ( nleft != NULL ) { nleft->depth=get_nbit(size)-1; nleft->value=0; } } else { x0=*rx0; if ( ! ( 0 <= compare(index[size-1],x0,param) ) ) /* II */ { *rleft=1; *rright=0; return(1); } min=0; max=size; n.depth=0; n.value=0; mask=1; while ( max>min+1 ) { mid=(min+max)/2; if ( 0 <= compare(index[mid-1],x0,param) ) /* II */ max=mid; else min=mid, n.value|=mask; n.depth++; mask<<=1; } *rleft=min; if ( nleft != NULL ) { nleft->depth=n.depth; nleft->value=n.value; } } if ( rx1==NULL ) { *rright=size-1; if ( nright != NULL ) { nright->depth=get_nbit(size-1); nright->value=(1<depth)-1; }; } else { x1=*rx1; if ( ! ( compare(index[0],x1,param)<=0 ) ) /* II */ { *rleft=1; *rright=0; return(1); } min=0; max=size; n.depth=0; n.value=0; mask=1; while ( max>min+1 ) { mid=(min+max)/2; if ( compare(index[mid],x1,param)<=0 ) /* II */ min=mid, n.value|=mask; else max=mid; n.depth++; mask<<=1; }; *rright=min; if ( nleft != NULL ) { nright->depth=n.depth; nright->value=n.value; } } if ( *rleft > *rright ) return(1); /* epmty interval */ else return(0); } /*****************************************************************************/ /* functions related to walking on a static binary tree */ int get_nodeinterval_rec(int ileft,int iright,int min,int max, int depth,int value,nodeinterval **nis) { int nnileft,nniright,mid; if ( iright < min || max <= ileft ) return(0); else if ( ileft<=min && max-1<=iright ) { (*nis)->i.depth=depth; (*nis)->i.value=value; (*nis)->min=min; (*nis)->max=max; (*nis)++; return(1); } else { mid=(min+max)/2; nnileft =get_nodeinterval_rec(ileft,iright, min,mid,depth+1,value,nis); nniright=get_nodeinterval_rec(ileft,iright, mid,max,depth+1,value|(1<param=param; mi->size=size; mi->nbit=nbit; mi->i_pri=(int *)malloc(sizeof(int)*size); mi->i_sec=(int *)malloc(sizeof(int)*size*nbit); mi->ind_x=mi->i_pri; for ( i=0 ; iind_x[i]=i; } mi->ind_xy=(int **)malloc(sizeof(int *)*nbit); for ( i=0 ; iind_xy[i]=&mi->i_sec[size*i]; } index_quicksort(mi->ind_x,size,compare_x,param); for ( i=0 ; iind_xy[i],mi->ind_x,sizeof(int)*size); index_subsort(mi->ind_xy[i],compare_y,i,0,size,param); } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int multiindex_range_query(multiindex *mi, int (*compare_value_x)(int,double,void *), int (*compare_value_y)(int,double,void *), double xl,double xr,double yl,double yr, int *ret,int maxret) { int il,ir,iyl,iyr,nni,maxdepth; int *lindy,depth,min,max,i,j,k,nret; nodeinterval *nis; if ( mi==NULL ) return(-1); if ( mi->param==NULL || mi->ind_x==NULL || mi->ind_xy==NULL ) return(-1); search_index_boundaries(mi->param,mi->ind_x,mi->size,compare_value_x, &xl,&il,NULL,&xr,&ir,NULL); nis=(nodeinterval *)malloc(sizeof(nodeinterval)*2*mi->nbit); nni=get_nodeintervals(il,ir,mi->size,nis); maxdepth=mi->nbit; nret=0; for ( i=0 ; i= maxdepth || depth >= mi->nbit ) { for ( j=min ; jind_x[j]; if ( ! check_if_in_interval(mi->param,k, compare_value_y,&yl,&yr) ) continue; else if ( nretind_xy[depth]; search_index_boundaries(mi->param,lindy+min,max-min, compare_value_y,&yl,&iyl,NULL,&yr,&iyr,NULL); iyl+=min; iyr+=min; for ( j=iyl ; j<=iyr ; j++ ) { k=lindy[j]; if ( nretnbit=mi->size=0; mi->param=NULL; mi->i_pri=mi->i_sec=NULL; mi->ind_x=NULL; mi->ind_xy=NULL; return(0); } int multiindex_free(multiindex *mi) { if ( mi==NULL ) return(-1); if ( mi->i_pri != NULL ) free(mi->i_pri); if ( mi->i_sec != NULL ) free(mi->i_sec); if ( mi->ind_xy != NULL ) free(mi->ind_xy); multiindex_reset(mi); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/lfit-builtin.c0000644000175000017500000010604512771246331014624 0ustar apalapal/*****************************************************************************/ /* lfit-builtin.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* LFIT - Symbolic fitting & arithmetic evaluating utility. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file defines the built-in functions available in LFIT by default. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 1996, 2002, 2004-2005, 2006, 2007-2008; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #if defined _CHDET_SOURCE #include "psn.h" #elif defined _FITSH_SOURCE #include #else #include #endif #if defined _FITSH_SOURCE #include "math/elliptic/elliptic.h" #include "math/elliptic/ntiq.h" #include "math/spline/spline.h" #include "xfunct.h" #elif defined _ASTRO_EXTEN #include "elliptic/elliptic.h" #include "elliptic/ntiq.h" #include "spline/spline.h" #include "xfunct.h" #endif #include #include "lfit-builtin.h" #ifndef M_PI #define M_PI 3.1415926535897932384626433832795028841968 #endif #ifndef M_LN10 #define M_LN10 2.3025850929940456840179914546843642076011 #endif #ifndef M_LOG10E #define M_LOG10E 0.4342944819032518276511289189166050822943 #endif /*****************************************************************************/ static int bltf_o_add(double *s) { *(s-2)=(*(s-2))+(*(s-1));return(0); } static int bltf_o_sub(double *s) { *(s-2)=(*(s-2))-(*(s-1));return(0); } static int bltf_o_mul(double *s) { *(s-2)=(*(s-2))*(*(s-1));return(0); } static int bltf_o_div(double *s) { if ( *(s-1)==0.0 ) return(1); *(s-2)=(*(s-2))/(*(s-1));return(0); } static int bltf_o_pow(double *s) { *(s-2)=pow(*(s-2),*(s-1)); return(0); } static int bltf_o_chs(double *s) { *(s-1)=-(*(s-1));return(0); } static int bltf_o_psq(double *s) { s--,(*s)*=*s;return(0); } static int bltf_o_rcp(double *s) { s--;if ( *s==0.0 ) return(1); *s=1.0/(*s);return(0); } static int bltf_o_sqr(double *s) { s--;if ( *s<0.0 ) return(1); *s=sqrt(*s);return(0); } static int bltf_o_abs(double *s) { s--;*s=fabs(*s);return(0); } static int bltf_o_sgn(double *s) { s--; if ( *s>0 ) *s=1.0; else if ( *s<0 ) *s=-1.0; else *s=0.0; return(0); } static int bltf_o_theta(double *s) { s--;if ( *s>0 ) *s=1.0; else if ( *s<0 ) *s=0.0; else *s=0.5; return(0); } static int bltf_o_fmod(double *s) { double m,d;int k; s-=2;m=*s,d=*(s+1); if ( d<0.0 ) d=-d; else if ( d==0.0 ) return(1); if ( m<0.0 ) k=(int)((-m)/d),m+=d*(double)(k+2); k=(int)(m/d),m-=(double)k*d; *s=m;return(0); } static int bltf_o_fint(double *s) { s--;*s=floor(*s);return(0); } static int bltf_o_fdiv(double *s) { double m,d; s-=2;m=*s,d=*(s+1); if ( d<0.0 ) d=-d; else if ( d==0.0 ) return(1); m=floor(m/d); *s=m;return(0); } static int bltf_o_vpi(double *s) { *s=M_PI;return(0); } static int bltf_f_arg(double *s) { s-=2; *s=atan2(*(s+1),*(s));return(0); } static int bltf_f_atan2(double *s) { s-=2; *s=atan2(*(s),*(s+1));return(0); } static int bltf_f_hypot(double *s) { s-=2; *s=sqrt((*s)*(*s)+(*(s+1))*(*(s+1)));return(0); } static int bltf_f_exp(double *s) { s--;*s=exp(*s);return(0); } static int bltf_f_log(double *s) { s--;if ( *s<=0.0 ) return(1); *s=log(*s);return(0); } static int bltf_f_exp10(double *s) { s--;*s=exp(*s*(M_LN10));return(0); } static int bltf_f_log10(double *s) { s--;if ( *s<=0.0 ) return(1); *s=log(*s)*M_LOG10E;return(0); } static int bltf_f_sin(double *s) { *(s-1)=sin(*(s-1));return(0); } static int bltf_f_cos(double *s) { *(s-1)=cos(*(s-1));return(0); } static int bltf_f_tan(double *s) { *(s-1)=tan(*(s-1));return(0); } static int bltf_f_ctn(double *s) { *(s-1)=1.0/tan(*(s-1));return(0); } static int bltf_f_sina(double *s) { *(s-1)=sin(*(s-1)*M_PI/180.0);return(0); } static int bltf_f_cosa(double *s) { *(s-1)=cos(*(s-1)*M_PI/180.0);return(0); } static int bltf_f_tana(double *s) { *(s-1)=tan(*(s-1)*M_PI/180.0);return(0); } static int bltf_f_ctna(double *s) { *(s-1)=1.0/tan(*(s-1)*M_PI/180.0);return(0); } static int bltf_f_asin(double *s) { *(s-1)=asin(*(s-1));return(0); } static int bltf_f_acos(double *s) { *(s-1)=acos(*(s-1));return(0); } static int bltf_f_atan(double *s) { *(s-1)=atan(*(s-1));return(0); } static int bltf_f_actn(double *s) { *(s-1)=atan(1.0/(*(s-1)));return(0); } static int bltf_f_asina(double *s) { *(s-1)=asin(*(s-1))*180.0/M_PI;return(0); } static int bltf_f_acosa(double *s) { *(s-1)=acos(*(s-1))*180.0/M_PI;return(0); } static int bltf_f_atana(double *s) { *(s-1)=atan(*(s-1))*180.0/M_PI;return(0); } static int bltf_f_actna(double *s) { *(s-1)=atan(1.0/(*(s-1)))*180.0/M_PI;return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int bltf_f_ilinear(double *s) { int b; double x,r; s-=3; b=(int)s[1]; x=s[2]; if ( x <= b-1 ) r=0.0; else if ( x <= b ) r=1.0-(b-x); else if ( x < b+1 ) r=1.0-(x-b); else r=0.0; *s=r; return(0); } static int bltf_f_ilinear_dx(double *s) { int b; double x,r; s-=3; b=(int)s[1]; x=s[2]; if ( x <= b-1 ) r=0.0; else if ( x <= b ) r=+1.0; else if ( x < b+1 ) r=-1.0; else r=0.0; *s=r; return(0); } static int bltf_f_ispline(double *s) { static int t_save=0; static double *arr=NULL; int n,t,b; double x,r; s-=3; n=(int)s[0]; b=(int)s[1]; x=s[2]; if ( n<0 || ! ( 0<=b && b<=n ) ) return(-1); if ( x<0 ) x=0.0; else if ( x>n ) x=(double)n; t=n+1; if ( t_save != t ) { int i,j; t_save=t; if ( arr != NULL ) { free(arr); arr=NULL; } arr=(double *)malloc(sizeof(double)*(2*t*t)); for ( i=0 ; in ) x=(double)n; t=n+1; if ( t_save != t ) { int i,j; t_save=t; if ( arr != NULL ) { free(arr); arr=NULL; } arr=(double *)malloc(sizeof(double)*(2*t*t)); for ( i=0 ; i *(s-1) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int bltf_o_le(double *s) { if ( *(s-2)<=*(s-1) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int bltf_o_ge(double *s) { if ( *(s-2)>=*(s-1) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int bltf_o_and(double *s) { if ( *(s-1)!=0 && *(s-2)!=0 ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int bltf_o_or(double *s) { if ( *(s-1)!=0 || *(s-2)!=0 ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } /*****************************************************************************/ /* Derivative rules */ static short diffrule_o_add[]={ SS_D2,SS_D1,O_ADD,0 }; static short diffrule_o_sub[]={ SS_D2,SS_D1,O_SUB,0 }; static short diffrule_o_mul[]={ SS_D2,SS_N1,O_MUL,SS_D1,SS_N2,O_MUL,O_ADD,0 }; static short diffrule_o_div[]={ SS_D2,SS_N1,O_MUL,SS_D1,SS_N2,O_MUL,O_SUB,SS_N1,O_PSQ,O_DIV,0 }; static short diffrule_o_pow[]={ SS_N2,SS_N1,O_POW,SS_D1,O_MUL,SS_N2,F_LOG,O_MUL,SS_N2,SS_N1,CON_1,O_SUB,O_POW,SS_N1,O_MUL,SS_D2,O_MUL,O_ADD,0 }; static short diffrule_o_chs[]={ SS_D1,O_CHS,0 }; static short diffrule_o_psq[]={ SS_N1,CON_2,O_MUL,SS_D1,O_MUL,0 }; static short diffrule_o_rcp[]={ SS_N1,O_PSQ,O_RCP,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_sqr[]={ SS_N1,F_SQR,CON_2,O_MUL,O_RCP,SS_D1,O_MUL,0 }; static short diffrule_f_abs[]={ SS_N1,F_SGN,SS_D1,O_MUL,0 }; static short diffrule_f_sgn[] ={ CON_0,0 }; static short diffrule_f_theta[]={ CON_0,0 }; static short diffrule_f_fmod[]={ SS_D2,SS_N2,SS_N1,O_DIV,F_FINT,SS_D1,O_MUL,O_SUB,0 }; static short diffrule_f_fint[]={ CON_0,0 }; static short diffrule_f_fdiv[]={ CON_0,0 }; static short diffrule_f_vpi[]={ CON_0,0 }; static short diffrule_f_arg []={ SS_N2,SS_D1,O_MUL,SS_N1,SS_D2,O_MUL,O_SUB,SS_N1,O_PSQ,SS_N2,O_PSQ,O_ADD,O_DIV,0 }; static short diffrule_f_atan2[]={ SS_N1,SS_D2,O_MUL,SS_N2,SS_D1,O_MUL,O_SUB,SS_N1,O_PSQ,SS_N2,O_PSQ,O_ADD,O_DIV,0 }; static short diffrule_f_hypot[]={ SS_N1,SS_D1,O_MUL,SS_N2,SS_D2,O_MUL,O_ADD,SS_N1,SS_N2,F_HYPOT,O_DIV,0 }; static short diffrule_f_sin[]={ SS_N1,F_COS,SS_D1,O_MUL,0 }; static short diffrule_f_cos[]={ SS_N1,F_SIN,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_tan[]={ SS_N1,F_COS,O_PSQ,O_RCP,SS_D1,O_MUL,0 }; static short diffrule_f_ctn[]={ SS_N1,F_SIN,O_PSQ,O_RCP,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_asin[]={ SS_D1,CON_1,SS_N1,O_PSQ,O_SUB,F_SQR,O_DIV,0 }; static short diffrule_f_acos[]={ SS_D1,CON_1,SS_N1,O_PSQ,O_SUB,F_SQR,O_DIV,O_CHS,0 }; static short diffrule_f_atan[]={ SS_D1,CON_1,SS_N1,O_PSQ,O_ADD,O_DIV,0 }; static short diffrule_f_actn[]={ SS_D1,CON_1,SS_N1,O_PSQ,O_ADD,O_DIV,O_CHS }; static short diffrule_f_exp[]={ SS_N1,F_EXP,SS_D1,O_MUL,0 }; static short diffrule_f_log[]={ SS_N1,O_RCP,SS_D1,O_MUL,0 }; static short diffrule_f_ilinear[] = { SS_N3,SS_N2,SS_N1,F_ILINEAR_DX,SS_D1,O_MUL,0 }; static short diffrule_f_ispline[] = { SS_N3,SS_N2,SS_N1,F_ISPLINE_DX,SS_D1,O_MUL,0 }; static short diffrule_f_icyspline[] = { SS_N2,SS_N1,F_ICYSPLINE_DX,SS_D1,O_MUL,0 }; static short diffrule_f_jbessel[] = { SS_N2,CON_1,O_SUB,SS_N1,F_JBESSEL,SS_N2,CON_1,O_ADD,SS_N1,F_JBESSEL,O_SUB,CON_2,O_DIV,SS_D1,O_MUL,0 }; static short diffrule_f_ybessel[] = { SS_N2,CON_1,O_SUB,SS_N1,F_YBESSEL,SS_N2,CON_1,O_ADD,SS_N1,F_YBESSEL,O_SUB,CON_2,O_DIV,SS_D1,O_MUL,0 }; /* Simplification rules: */ /* Type */ static short sim_o_add1[]={ S_EXP1,CON_0,O_ADD,0,S_EXP1,0 }; /* expr+0=expr */ static short sim_o_add2[]={ CON_0,S_EXP1,O_ADD,0,S_EXP1,0 }; /* 0+expr=expr */ static short sim_o_sub1[]={ S_EXP1,CON_0,O_SUB,0,S_EXP1,0 }; /* expr-0=expr */ static short sim_o_sub2[]={ CON_0,S_EXP1,O_SUB,0,S_EXP1,O_CHS,0 }; /* 0-expr=-expr */ static short sim_o_mul1[]={ S_EXP1,CON_1 ,O_MUL,0,S_EXP1,0 }; /* expr*1=expr */ static short sim_o_mul2[]={ CON_1 ,S_EXP1,O_MUL,0,S_EXP1,0 }; /* 1*expr=expr */ static short sim_o_mul3[]={ S_EXP1,CON_0 ,O_MUL,0,CON_0,0 }; /* expr*0=0 */ static short sim_o_mul4[]={ CON_0 ,S_EXP1,O_MUL,0,CON_0,0 }; /* 0*expr=0 */ static short sim_o_mul5[]={ S_EXP1,S_EXP1,O_MUL,0,S_EXP1,O_PSQ,0 }; /* ex*ex=ex^(2) */ static short sim_o_div1[]={ S_EXP1,CON_1 ,O_DIV,0,S_EXP1,0 }; /* expr/1=expr */ static short sim_o_div2[]={ CON_1 ,S_EXP1,O_DIV,0,S_EXP1,O_RCP,0 }; /* 1/expr=expr^(-1) */ static short sim_o_div3[]={ S_EXP1,CON_0 ,O_DIV,0,0 }; /* expr/0=UNDEF! */ static short sim_o_div4[]={ CON_0 ,S_EXP1,O_DIV,0,CON_0 ,0 }; /* 0/expr=0 */ static short sim_o_pow1[]={ S_EXP1,CON_0,O_POW,0,CON_1 ,0 }; /* ex^0=1 */ static short sim_o_pow2[]={ S_EXP1,CON_1,O_POW,0,S_EXP1,0 }; /* ex^1=ex */ static short sim_o_pow3[]={ S_EXP1,CON_2,O_POW,0,S_EXP1,O_PSQ,0 }; /* ex^2=ex PSQ */ static short sim_addmul_dis1[]={ S_EXP1,S_EXP2,O_MUL,S_EXP1,S_EXP3,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* a*b+a*c=a*(b+c) */ static short sim_addmul_dis2[]={ S_EXP2,S_EXP1,O_MUL,S_EXP1,S_EXP3,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* a*b+c*a=a*(b+c) */ static short sim_addmul_dis3[]={ S_EXP1,S_EXP2,O_MUL,S_EXP3,S_EXP1,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* b*a+a*c=a*(b+c) */ static short sim_addmul_dis4[]={ S_EXP2,S_EXP1,O_MUL,S_EXP3,S_EXP1,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* b*a+c*a=a*(b+c) */ static short sim_submul_dis1[]={ S_EXP1,S_EXP2,O_MUL,S_EXP1,S_EXP3,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* a*b-a*c=a*(b-c) */ static short sim_submul_dis2[]={ S_EXP2,S_EXP1,O_MUL,S_EXP1,S_EXP3,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* a*b-c*a=a*(b-c) */ static short sim_submul_dis3[]={ S_EXP1,S_EXP2,O_MUL,S_EXP3,S_EXP1,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* b*a-a*c=a*(b-c) */ static short sim_submul_dis4[]={ S_EXP2,S_EXP1,O_MUL,S_EXP3,S_EXP1,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* b*a-c*a=a*(b-c) */ static short sim_adddiv_dis []={ S_EXP2,S_EXP1,O_DIV,S_EXP3,S_EXP1,O_DIV,O_ADD,0,S_EXP2,S_EXP3,O_ADD,S_EXP1,O_DIV,0 }; /* b/a+c/a=(b+c)/a */ static short sim_subdiv_dis []={ S_EXP2,S_EXP1,O_DIV,S_EXP3,S_EXP1,O_DIV,O_SUB,0,S_EXP2,S_EXP3,O_SUB,S_EXP1,O_DIV,0 }; /* b/a-c/a=(b-c)/a */ static short sim_mulpow_dis []={ S_EXP2,S_EXP1,O_POW,S_EXP3,S_EXP1,O_POW,O_MUL,0,S_EXP2,S_EXP3,O_MUL,S_EXP1,O_POW,0 }; /* b^a*c^a=(b*c)^a */ static short sim_divpow_dis []={ S_EXP2,S_EXP1,O_POW,S_EXP3,S_EXP1,O_POW,O_DIV,0,S_EXP2,S_EXP3,O_DIV,S_EXP1,O_POW,0 }; /* b^a/c^a=(b/c)^a */ static short sim_tau1[]= { S_EXP1,S_EXP2,O_CHS,O_SUB,0,S_EXP1,S_EXP2,O_ADD,0 }; /* a-(-b)=a+b */ static short sim_gon1[]= { S_EXP1,F_SIN,O_PSQ,S_EXP1,F_COS,O_PSQ,O_ADD,0,CON_1,0 }; /* sin^2(x)+cos^2(x)=1 */ short *psn_lfit_simp[]= { sim_o_add1, sim_o_add2, sim_o_sub1, sim_o_sub2, sim_o_mul1, sim_o_mul2, sim_o_mul3, sim_o_mul4, sim_o_mul5, sim_o_div1, sim_o_div2, sim_o_div3, sim_o_div4, sim_o_pow1, sim_o_pow2, sim_o_pow3, sim_addmul_dis1, sim_addmul_dis2, sim_addmul_dis3, sim_addmul_dis4, sim_submul_dis1, sim_submul_dis2, sim_submul_dis3, sim_submul_dis4, sim_adddiv_dis, sim_subdiv_dis, sim_mulpow_dis, sim_divpow_dis, sim_tau1, sim_gon1, NULL }; static psnfunctinfo pfi_add = { "addition" }; static psnfunctinfo pfi_sub = { "subtraction" }; static psnfunctinfo pfi_chs = { "negation" }; static psnfunctinfo pfi_mul = { "multiplication" }; static psnfunctinfo pfi_div = { "division" }; static psnfunctinfo pfi_pow = { "power (right-associative)" }; static psnfunctinfo pfi_sin = { "sine function (argument in radians)" }; static psnfunctinfo pfi_cos = { "cosine function (argument in radians)" }; static psnfunctinfo pfi_tan = { "tangent function (argument in radians)" }; static psnfunctinfo pfi_cot = { "cotangent function (argument in radians)" }; static psnfunctinfo pfi_asin = { "inverse sine function (results radians)" }; static psnfunctinfo pfi_acos = { "inverse cosine function (results radians)" }; static psnfunctinfo pfi_atan = { "inverse tangent function (results radians)" }; static psnfunctinfo pfi_acot = { "inverse cotangent function (results radians)" }; static psnfunctinfo pfi_exp = { "exponential function (natural, e-based)" }; static psnfunctinfo pfi_log = { "natural logarithm" }; static psnfunctinfo pfi_exp10 = { "exponential function (base 10)" }; static psnfunctinfo pfi_log10 = { "logarithm to the base 10" }; static psnfunctinfo pfi_sgn = { "sign function" }; static psnfunctinfo pfi_theta = { "Heaviside step function" }; static psnfunctinfo pfi_abs = { "absolute value function" }; static psnfunctinfo pfi_sqrt = { "square root function" }; static psnfunctinfo pfi_fint = { "integer part function (i.e. results the largest integer which is not larger than the argument)" }; static psnfunctinfo pfi_fdiv = { "integer division, div(x,y) is equivalent to int(x/y)" }; static psnfunctinfo pfi_fmod = { "real fractional remainder function" }; static psnfunctinfo pfi_arg = { "two dimensional argument function (results radians)" }; static psnfunctinfo pfi_atan2 = { "two dimensional argument function, as defined in some programming languages, i.e. atan2(y,x)=arg(x,y) (results radians)" }; static psnfunctinfo pfi_hypot = { "hypotenuse function, it results the hypotenuse of a right triangle of which catheti are the two arguments of the function" }; static psnfunctinfo pfi_vpi = { "results the value of \\pi (a function with no arguments)" }; static psnfunctinfo pfi_ilinear = { "base function of linear interpolation" }; static psnfunctinfo pfi_ispline = { "base function of cubic spline interpolation" }; static psnfunctinfo pfi_icyspline = { "base function of cyclic cubic spline interpolation" }; static psnfunctinfo pfi_jbessel = { "Bessel function of the first kind" }; static psnfunctinfo pfi_ybessel = { "Bessel function of the second kind" }; /*****************************************************************************/ /*| sym type major minor | #| P| assoc | (*funct)()| diffrule | symstring S affix | */ psnlfit psnlfit_list_builtin_normal_operators[]= { { "+" , T_OP, O_ADD , TO_INFIX , 2, 20, ASSOC_LEFT , bltf_o_add , diffrule_o_add , "#(1)+#(2)", 0, TO_INFIX , &pfi_add }, { "+" , T_OP, 0 , TO_PREFIX, 0, 0, 0 , NULL , NULL , NULL , 0, 0 , NULL }, { "-" , T_OP, O_SUB , TO_INFIX , 2, 20, ASSOC_LEFT , bltf_o_sub , diffrule_o_sub , "#(1)-#[2]", 0, TO_INFIX , &pfi_sub }, { "-" , T_OP, O_CHS , TO_PREFIX, 1, 22, 0 , bltf_o_chs , diffrule_o_chs , "(-#(1))" , 1, 0 , &pfi_chs }, { "*" , T_OP, O_MUL , TO_INFIX , 2, 21, ASSOC_LEFT , bltf_o_mul , diffrule_o_mul , "#(1)*#(2)", 0, TO_INFIX , &pfi_mul }, { "/" , T_OP, O_DIV , TO_INFIX , 2, 21, ASSOC_LEFT , bltf_o_div , diffrule_o_div , "#(1)/#[2]", 0, TO_INFIX , &pfi_div }, { "^" , T_OP, O_POW , TO_INFIX , 2, 23, ASSOC_RIGHT, bltf_o_pow , diffrule_o_pow , "#(1)^#(2)", 1, 0 , &pfi_pow }, { "RCP" , T_OP, O_RCP , 0 , 1, 23, 0 , bltf_o_rcp , diffrule_o_rcp , "1.0/#[1]" , 0, TO_INFIX , NULL }, { "PSQ" , T_OP, O_PSQ , 0 , 1, 23, 0 , bltf_o_psq , diffrule_o_psq , "#(1)^2" , 1, 0 , NULL }, { NULL , 0 , 0 , 0 , 0, 0, 0 , NULL , NULL , NULL , 0, 0 , NULL } }; psnlfit psnlfit_list_builtin_relational_operators[]= { { "==" , T_OP, O_EQU , TO_INFIX , 2, 10, ASSOC_LEFT , bltf_o_equ , NULL , NULL , 0, 0 , NULL }, { "!=" , T_OP, O_NEQ , TO_INFIX , 2, 10, ASSOC_LEFT , bltf_o_neq , NULL , NULL , 0, 0 , NULL }, { "<" , T_OP, O_LS , TO_INFIX , 2, 10, ASSOC_LEFT , bltf_o_ls , NULL , NULL , 0, 0 , NULL }, { ">" , T_OP, O_GR , TO_INFIX , 2, 10, ASSOC_LEFT , bltf_o_gr , NULL , NULL , 0, 0 , NULL }, { "<=" , T_OP, O_LE , TO_INFIX , 2, 10, ASSOC_LEFT , bltf_o_le , NULL , NULL , 0, 0 , NULL }, { ">=" , T_OP, O_GE , TO_INFIX , 2, 10, ASSOC_LEFT , bltf_o_ge , NULL , NULL , 0, 0 , NULL }, { "&&" , T_OP, O_AND , TO_INFIX , 2, 5, ASSOC_LEFT , bltf_o_and , NULL , NULL , 0, 0 , NULL }, { "||" , T_OP, O_OR , TO_INFIX , 2, 4, ASSOC_LEFT , bltf_o_or , NULL , NULL , 0, 0 , NULL }, { NULL , 0 , 0 , 0 , 0, 0, 0 , NULL , NULL , NULL , 0, 0 , NULL }, }; psnlfit psnlfit_list_builtin_elementary_functions[]= { { "sin" , T_FN, F_SIN , 0 , 1, 0, 0 , bltf_f_sin , diffrule_f_sin , "sin(#1)" , 0, 0 , &pfi_sin }, { "cos" , T_FN, F_COS , 0 , 1, 0, 0 , bltf_f_cos , diffrule_f_cos , "cos(#1)" , 0, 0 , &pfi_cos }, { "tan" , T_FN, F_TAN , 0 , 1, 0, 0 , bltf_f_tan , diffrule_f_tan , "tan(#1)" , 0, 0 , &pfi_tan }, { "cot" , T_FN, F_CTN , 0 , 1, 0, 0 , bltf_f_ctn , diffrule_f_ctn , "cot(#1)" , 0, 0 , &pfi_cot }, { "asin" , T_FN, F_ASIN , 0 , 1, 0, 0 , bltf_f_asin , diffrule_f_asin , "asin(#1)" , 0, 0 , &pfi_asin }, { "acos" , T_FN, F_ACOS , 0 , 1, 0, 0 , bltf_f_acos , diffrule_f_acos , "acos(#1)" , 0, 0 , &pfi_acos }, { "atan" , T_FN, F_ATAN , 0 , 1, 0, 0 , bltf_f_atan , diffrule_f_atan , "atan(#1)" , 0, 0 , &pfi_atan }, { "acot" , T_FN, F_ACTN , 0 , 1, 0, 0 , bltf_f_actn , diffrule_f_actn , "acot(#1)" , 0, 0 , &pfi_acot }, { "sina" , T_FN, F_SINA , 0 , 1, 0, 0 , bltf_f_sina , NULL , "sina(#1)" , 0, 0 , NULL }, { "cosa" , T_FN, F_COSA , 0 , 1, 0, 0 , bltf_f_cosa , NULL , "cosa(#1)" , 0, 0 , NULL }, { "tana" , T_FN, F_TANA , 0 , 1, 0, 0 , bltf_f_tana , NULL , "tana(#1)" , 0, 0 , NULL }, { "ctga" , T_FN, F_CTNA , 0 , 1, 0, 0 , bltf_f_ctna , NULL , "ctna(#1)" , 0, 0 , NULL }, { "asina", T_FN, F_ASINA, 0 , 1, 0, 0 , bltf_f_asina, NULL , "asina(#1)" , 0, 0 , NULL }, { "acosa", T_FN, F_ACOSA, 0 , 1, 0, 0 , bltf_f_acosa, NULL , "acosa(#1)" , 0, 0 , NULL }, { "atana", T_FN, F_ATANA, 0 , 1, 0, 0 , bltf_f_atana, NULL , "atana(#1)" , 0, 0 , NULL }, { "actga", T_FN, F_ACTNA, 0 , 1, 0, 0 , bltf_f_actna, NULL , "actna(#1)" , 0, 0 , NULL }, { "exp" , T_FN, F_EXP , 0 , 1, 0, 0 , bltf_f_exp , diffrule_f_exp , "exp(#1)" , 0, 0 , &pfi_exp }, { "log" , T_FN, F_LOG , 0 , 1, 0, 0 , bltf_f_log , diffrule_f_log , "log(#1)" , 0, 0 , &pfi_log }, { "exp10", T_FN, F_EXP10, 0 , 1, 0, 0 , bltf_f_exp10, NULL , "exp10(#1)" , 0, 0 , &pfi_exp10}, { "log10", T_FN, F_LOG10, 0 , 1, 0, 0 , bltf_f_log10, NULL , "log10(#1)" , 0, 0 , &pfi_log10}, { "sqrt" , T_FN, F_SQR , 0 , 1, 0, 0 , bltf_o_sqr , diffrule_f_sqr , "sqrt(#1)" , 0, 0 , &pfi_sqrt }, { "abs" , T_FN, F_ABS , 0 , 1, 0, 0 , bltf_o_abs , diffrule_f_abs , "abs(#1)" , 0, 0 , &pfi_abs }, { "sign" , T_FN, F_SGN , 0 , 1, 0, 0 , bltf_o_sgn , diffrule_f_sgn , "sign(#1)" , 0, 0 , &pfi_sgn }, { "theta", T_FN, F_THETA, 0 , 1, 0, 0 , bltf_o_theta, diffrule_f_theta, "theta(#1)" , 0, 0 , &pfi_theta}, { "int" , T_FN, F_FINT , 0 , 1, 0, 0 , bltf_o_fint , diffrule_f_fint , "int(#1)" , 0, 0 , &pfi_fint }, { "div" , T_FN, F_FDIV , 0 , 2, 0, 0 , bltf_o_fdiv , diffrule_f_fdiv , "div(#1,#2)" , 0, 0 , &pfi_fdiv }, { "mod" , T_FN, F_FMOD , 0 , 2, 0, 0 , bltf_o_fmod , diffrule_f_fmod , "mod(#1,#2)" , 0, 0 , &pfi_fmod }, { "arg" , T_FN, F_ARG , 0 , 2, 0, 0 , bltf_f_arg , diffrule_f_arg , "arg(#1,#2)" , 0, 0 , &pfi_arg }, { "atan2", T_FN, F_ATAN2, 0 , 2, 0, 0 , bltf_f_atan2, diffrule_f_atan2, "atan2(#1,#2)", 0, 0 , &pfi_atan2}, { "hypot", T_FN, F_HYPOT, 0 , 2, 0, 0 , bltf_f_hypot, diffrule_f_hypot, "hypot(#1,#2)", 0, 0 , &pfi_hypot}, { "pi" , T_FN, F_VPI , 0 , 0, 0, 0 , bltf_o_vpi , diffrule_f_vpi , "pi()" , 0, 0 , &pfi_vpi }, { NULL , 0 , 0 , 0 , 0, 0, 0 , NULL , NULL , NULL , 0, 0 , NULL }, }; psnlfit psnlfit_list_builtin_interpolators[]= { { "ilinear" , T_FN, F_ILINEAR , 0 , 3, 0, 0 , bltf_f_ilinear , diffrule_f_ilinear , "ilinear(#1,#2,#3)" , 0, 0 , &pfi_ilinear }, { "ilinear_dx" , T_FN, F_ILINEAR_DX , 0 , 3, 0, 0 , bltf_f_ilinear_dx , NULL , "ilinear_dx(#1,#2,#3)" , 0, 0 , NULL }, { "ispline" , T_FN, F_ISPLINE , 0 , 3, 0, 0 , bltf_f_ispline , diffrule_f_ispline , "ispline(#1,#2,#3)" , 0, 0 , &pfi_ispline }, { "ispline_dx" , T_FN, F_ISPLINE_DX , 0 , 3, 0, 0 , bltf_f_ispline_dx , NULL , "ispline_dx(#1,#2,#3)" , 0, 0 , NULL }, { "icyspline" , T_FN, F_ICYSPLINE , 0 , 2, 0, 0 , bltf_f_icyspline , diffrule_f_icyspline, "icyspline(#1,#2)" , 0, 0 , &pfi_icyspline }, { "icyspline_dx", T_FN, F_ICYSPLINE_DX, 0 , 2, 0, 0 , bltf_f_icyspline_dx, NULL , "icyspline_dx(#1,#2)" , 0, 0 , NULL }, { NULL , 0 , 0 , 0 , 0, 0, 0 , NULL , NULL , NULL , 0, 0 , NULL }, }; psnlfit psnlfit_list_builtin_aa_functions[]= { { "jbessel", T_FN, F_JBESSEL, 0, 2, 0, 0, bltf_f_jbessel, diffrule_f_jbessel , "jbessel(#1,#2)", 0, 0 , &pfi_jbessel }, { "ybessel", T_FN, F_YBESSEL, 0, 2, 0, 0, bltf_f_ybessel, diffrule_f_ybessel , "ybessel(#1,#2)", 0, 0 , &pfi_ybessel }, { NULL , 0 , 0 , 0, 0, 0, 0, NULL , NULL , NULL , 0, 0 , NULL } }; /*****************************************************************************/ /* If 'lfit' is the part of the 'fi' package, we register some extra */ /* functions, declared and defined in xfunct.[ch]. */ /*****************************************************************************/ #if defined _FITSH_SOURCE || defined _ASTRO_EXTEN #define F_EOQ 96 /* eoq(), eccentric offset */ #define F_EOP 97 /* eop(), eccentric offset */ #define F_ETC 98 /* etc(), eccentric trig. */ #define F_ETS 99 /* ets(), eccentric trig. */ #define F_ELL_K 100 /* E() , ell. integral, 1st */ #define F_ELL_E 101 /* K() , ell. integral, 2nd */ #define F_ELL_PI 102 /* Pi(), ell. integral, 3rd */ #define F_NTIU 104 /* ntiu(), norm. trans. int. */ #define F_NTIQ 105 /* ntiq(), norm. trans. int. */ #define F_NTIQ_DP 106 /* ntiq_diff(): [0] */ #define F_NTIQ_DZ 107 /* ntiq_diff(): [1] */ #define F_NTIQ_DG1 108 /* ntiq_diff(): [2] */ #define F_NTIQ_DG2 109 /* ntiq_diff(): [3] */ #define F_HJD 110 /* hjd(), helocentric JD */ #define F_BJD 111 /* bjd(), barycentric JD */ static int funct_f_eoq(double *s) { s-=3; *s=eccentric_offset_q(*s,*(s+1),*(s+2)); return(0); } static short diffrule_f_eoq[]= { SS_N3,SS_N2,SS_N1,F_EOP,SS_N3,O_ADD,F_COS,SS_N2,O_SUB,SS_D2,O_MUL, SS_N3,SS_N2,SS_N1,F_EOP,SS_N3,O_ADD,F_SIN,SS_N1,O_SUB,SS_D1,O_MUL,O_ADD, SS_N3,SS_N2,SS_N1,F_EOP,SS_D3,O_MUL,O_SUB, CON_1,SS_N3,SS_N2,SS_N1,F_EOQ,O_SUB,O_DIV,0 }; static int funct_f_eop(double *s) { s-=3; *s=eccentric_offset_p(*s,*(s+1),*(s+2)); return(0); } static short diffrule_f_eop[]= { SS_N3,SS_N2,SS_N1,F_EOP,SS_N3,O_ADD,F_SIN,SS_D2,O_MUL, SS_N3,SS_N2,SS_N1,F_EOP,SS_N3,O_ADD,F_COS,SS_D1,O_MUL,O_SUB, SS_N3,SS_N2,SS_N1,F_EOQ,SS_D3,O_MUL,O_ADD, CON_1,SS_N3,SS_N2,SS_N1,F_EOQ,O_SUB,O_DIV,0 }; static int funct_f_etc(double *s) { s-=3; *s=cos((*s)+eccentric_offset_p(*s,*(s+1),*(s+2))); return(0); } static short diffrule_f_etc[]= { SS_N3,SS_N2,SS_N1,F_ETS,O_CHS,SS_D3,O_MUL, SS_N3,SS_N2,SS_N1,F_ETS,O_PSQ,SS_D2,O_MUL,O_SUB, SS_N3,SS_N2,SS_N1,F_ETS,SS_N3,SS_N2,SS_N1,F_ETC,O_MUL,SS_D1,O_MUL,O_ADD, CON_1,SS_N3,SS_N2,SS_N1,F_EOQ,O_SUB,O_DIV,0 }; static int funct_f_ets(double *s) { s-=3; *s=sin((*s)+eccentric_offset_p(*s,*(s+1),*(s+2))); return(0); } static short diffrule_f_ets[]= { SS_N3,SS_N2,SS_N1,F_ETC,SS_D3,O_MUL, SS_N3,SS_N2,SS_N1,F_ETS,SS_N3,SS_N2,SS_N1,F_ETC,O_MUL,SS_D2,O_MUL,O_ADD, SS_N3,SS_N2,SS_N1,F_ETC,O_PSQ,SS_D1,O_MUL,O_SUB, CON_1,SS_N3,SS_N2,SS_N1,F_EOQ,O_SUB,O_DIV,0 }; static int funct_f_ntiu(double *s) { s-=2; *s=1.0-ntiq(*s,*(s+1),0.0,0.0); return(0); } static short diffrule_f_ntiq[]= { SS_N4,SS_N3,SS_N2,SS_N1,F_NTIQ_DP ,SS_D4,O_MUL, SS_N4,SS_N3,SS_N2,SS_N1,F_NTIQ_DZ ,SS_D3,O_MUL,O_ADD, SS_N4,SS_N3,SS_N2,SS_N1,F_NTIQ_DG1,SS_D2,O_MUL,O_ADD, SS_N4,SS_N3,SS_N2,SS_N1,F_NTIQ_DG2,SS_D1,O_MUL,O_ADD,0 }; static int funct_f_ntiq_diff(double *s,double *out) { static double st_args[4]={1,5,0,0},st_diff[5]={0,0,0,0,0}; if ( memcmp(s,st_args,sizeof(double)*4) != 0 ) { memcpy(st_args,s,sizeof(double)*4); st_diff[4]=ntiq_diff(s[0],s[1],s[2],s[3],st_diff); } memcpy(out,st_diff,sizeof(double)*5); return(0); } static int funct_f_ntiq(double *s) { double st_diff[5]; s-=4; funct_f_ntiq_diff(s,st_diff); *s=(1.0-st_diff[4]); return(0); } static int funct_f_ntiq_dp(double *s) { double st_diff[5]; s-=4; funct_f_ntiq_diff(s,st_diff); *s=(-st_diff[0]); return(0); } static int funct_f_ntiq_dz(double *s) { double st_diff[5]; s-=4; funct_f_ntiq_diff(s,st_diff); *s=(-st_diff[1]); return(0); } static int funct_f_ntiq_dg1(double *s) { double st_diff[5]; s-=4; funct_f_ntiq_diff(s,st_diff); *s=(-st_diff[2]); return(0); } static int funct_f_ntiq_dg2(double *s) { double st_diff[5]; s-=4; funct_f_ntiq_diff(s,st_diff); *s=(-st_diff[3]); return(0); } static int funct_f_hjd(double *s) { s-=3; *s=get_hjd(*s,*(s+1),*(s+2)); return(0); } static int funct_f_bjd(double *s) { s-=3; *s=get_bjd(*s,*(s+1),*(s+2)); return(0); } static int funct_f_elliptic_k(double *s) { s-=1; if ( fabs(*s) < 1.0 ) { *s=elliptic_complete_first(*s); return(0); } else return(1); } static int funct_f_elliptic_e(double *s) { s-=1; if ( fabs(*s) <= 1.0 ) { *s=elliptic_complete_second(*s); return(0); } else return(1); } static int funct_f_elliptic_pi(double *s) { s-=2; if ( *s < 1.0 && fabs(*(s+1)) < 1.0 ) { *s=elliptic_complete_third(*s,*(s+1)); return(0); } else return(1); } static psnfunctinfo pfi_eoq = { "eccentric offset function, `q` component (arguments: mean longitude in radians, k and h Lagrangian elements)" }; static psnfunctinfo pfi_eop = { "eccentric offset function, `p` component (arguments: mean longitude in radians, k and h Lagrangian elements)" }; static psnfunctinfo pfi_etc = { "eccentric trigonometric function, cosine component (arguments: mean longitude in radians, k and h Lagrangian elements)" }; static psnfunctinfo pfi_ets = { "eccentric trigonometric function, sine component (arguments: mean longitude in radians, k and h Lagrangian elements)" }; static psnfunctinfo pfi_ntiu = { "normalized transit intensity - uniform flux distribution (arguments: fractional radius, normalized distance)" }; static psnfunctinfo pfi_ntiq = { "normalized transit intensity - quadratic limb darkening assumption (arguments: fracional radius, normalized distance, the two limb darkening coefficients)" }; static psnfunctinfo pfi_hjd = { "heliocentric Julian date (arguments: julian day, RA and DEC, in degrees)" }; static psnfunctinfo pfi_bjd = { "barycentric Julian date (arguments: julian day, RA and DEC, in degrees)" }; static psnfunctinfo pfi_ell_k = { "complete elliptic integral of the first kind" }; static psnfunctinfo pfi_ell_e = { "complete elliptic integral of the second kind" }; static psnfunctinfo pfi_ell_pi = { "complete elliptic integral of the third kind" }; psnlfit psnlfit_list_builtin_xfuncts[]= { { "eoq" , T_FN, F_EOQ , 0 , 3, 0, 0 , funct_f_eoq , diffrule_f_eoq , "eoq(#1,#2,#3)" , 0, 0 , &pfi_eoq }, { "eop" , T_FN, F_EOP , 0 , 3, 0, 0 , funct_f_eop , diffrule_f_eop , "eop(#1,#2,#3)" , 0, 0 , &pfi_eop }, { "etc" , T_FN, F_ETC , 0 , 3, 0, 0 , funct_f_etc , diffrule_f_etc , "etc(#1,#2,#3)" , 0, 0 , &pfi_etc }, { "ets" , T_FN, F_ETS , 0 , 3, 0, 0 , funct_f_ets , diffrule_f_ets , "ets(#1,#2,#3)" , 0, 0 , &pfi_ets }, { "ntiu" , T_FN, F_NTIU , 0 , 2, 0, 0 , funct_f_ntiu , NULL , "ntiu(#1,#2)" , 0, 0 , &pfi_ntiu }, { "ntiq" , T_FN, F_NTIQ , 0 , 4, 0, 0 , funct_f_ntiq , diffrule_f_ntiq , "ntiq(#1,#2,#3,#4)" , 0, 0 , &pfi_ntiq }, { "ntiq_dp" , T_FN, F_NTIQ_DP , 0 , 4, 0, 0 , funct_f_ntiq_dp , NULL , "ntiq_dp(#1,#2,#3,#4)" , 0, 0 , NULL }, { "ntiq_dz" , T_FN, F_NTIQ_DZ , 0 , 4, 0, 0 , funct_f_ntiq_dz , NULL , "ntiq_dz(#1,#2,#3,#4)" , 0, 0 , NULL }, { "ntiq_dg1" , T_FN, F_NTIQ_DG1, 0 , 4, 0, 0 , funct_f_ntiq_dg1 , NULL , "ntiq_dg1(#1,#2,#3,#4)", 0, 0 , NULL }, { "ntiq_dg2" , T_FN, F_NTIQ_DG2, 0 , 4, 0, 0 , funct_f_ntiq_dg2 , NULL , "ntiq_dg2(#1,#2,#3,#4)", 0, 0 , NULL }, { "hjd" , T_FN, F_HJD , 0 , 3, 0, 0 , funct_f_hjd , NULL , "hjd(#1,#2,#3)" , 0, 0 , &pfi_hjd }, { "bjd" , T_FN, F_BJD , 0 , 3, 0, 0 , funct_f_bjd , NULL , "bjd(#1,#2,#3)" , 0, 0 , &pfi_bjd }, { "ellipticK" , T_FN, F_ELL_K , 0 , 1, 0, 0 , funct_f_elliptic_k , NULL , "ellipticK(#1)" , 0, 0 , &pfi_ell_k }, { "ellipticE" , T_FN, F_ELL_E , 0 , 1, 0, 0 , funct_f_elliptic_e , NULL , "ellipticE(#1)" , 0, 0 , &pfi_ell_e }, { "ellipticPi", T_FN, F_ELL_PI , 0 , 2, 0, 0 , funct_f_elliptic_pi, NULL , "ellipticPi(#1)" , 0, 0 , &pfi_ell_pi }, { NULL , 0 , 0 , 0 , 0, 0, 0 , NULL , NULL , NULL , 0, 0 , NULL } }; #endif /*****************************************************************************/ fitsh-0.9.2/src/fitsh.h0000644000175000017500000000754312771247666013363 0ustar apalapal/*****************************************************************************/ /* fitsh.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Global configuration stuff for FITSH package... */ /*****************************************************************************/ #ifndef __FITSH_H_INCLUDED #define __FITSH_H_INCLUDED 1 /*****************************************************************************/ #include "longhelp.h" #include "../config.h" /*****************************************************************************/ /* It's the exact value: */ #define SIG_FWHM (2.354820045030949382) /* in the previous releases (<0.9c0) it was 2.35. */ /*****************************************************************************/ #define MASK_OK 0x00 /* everything is ok... */ #define MASK_CLEAR MASK_OK /* alias */ #define MASK_FAULT 0x01 /* faulty pixel */ #define MASK_HOT 0x02 /* hot (nonlinear) pixel */ #define MASK_COSMIC 0x04 /* hit by a cosmic particle */ #define MASK_OUTER 0x08 /* outer pixel */ #define MASK_OVERSATURATED 0x10 /* oversaturated */ #define MASK_LEAKED 0x20 /* leaked (during readout) */ #define MASK_SATURATED (MASK_OVERSATURATED|MASK_LEAKED) #define MASK_INTERPOLATED 0x40 /* interpolated (not real) */ #define MASK_BAD 0x7F /* any error */ #define MASK_ALL 0x7F /* alias */ #define MASK_NOBACKGROUND 0x0100 /* indefinite background, not*/ /* used in a (char **) mask */ #define MASK_NAN MASK_FAULT /*****************************************************************************/ typedef struct { int code; char *message; } errormessage; /*****************************************************************************/ #define DEFAULT_MAX_MEMORY 8 /* in megabytes */ /*****************************************************************************/ /* print_error(), print_error_cmdline(): Prints the error with the specified code 'code' to the stream 'fw'. */ /* int print_error(FILE *fw,int code,...); int print_error_cmdline(FILE *fw,char *arg); */ /* print_warning(): Prints the warning message with the code 'code' to the stream 'fw'. */ /* int print_warning(FILE *fw,int code,...); */ char *get_progname(char *argv0); /* fprint_generic_version(): Print generic version information to the stream 'fw'. */ int fprint_generic_version(FILE *fw,char *arg0,char *name,char *pv,int type); int fprint_generic_long_help(FILE *fw,int is_wiki,longhelp_entry *help,char *synopsis,char *description); /* logmsg(): Writes the sprintf-formatted message 'msg' to stderr, if 'flag' is true. */ int logmsg(int flag,char *msg,...); /*****************************************************************************/ int parse_mask_flags(char *list); typedef struct { int bitpix; int is_scale; double bscale; double bzero; int nquantizebit; } fitsdataparam; /* parse_fits_data_param(): Parses the parameter string 'param' and sets the values in 'fdp'. If 'param' is NULL or some of the parameters are not defined, the default parameters (bitpix=0, bscale=1.0 and bzero=0.0) are set. */ int parse_fits_data_param(char *param,fitsdataparam *fdp); /*****************************************************************************/ /* is_nasty_char(), is_any_nasty_char(): These functions check whether is there any nasty characters (which are preprocessed by the standard unix command shells) in 't' and 'buff'. */ int is_nasty_char(int t); int is_any_nasty_char(char *buff); /*****************************************************************************/ size_t parse_max_memory_string(char *maxmemstr); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/background.h0000644000175000017500000000175011016674453014344 0ustar apalapal/*****************************************************************************/ /* background.h */ /*****************************************************************************/ #ifndef __BACKGROUND_H_DEFINED #define __BACKGROUND_H_DEFINED 1 /*****************************************************************************/ #define BACKGROUND_POLYNOMIAL 1 #define BACKGROUND_SPLINE 2 /*****************************************************************************/ typedef struct { int type,blocks,order; double sx,sy,scale; double *xfit,*yfit; } background; typedef struct { int order; double ox,oy,scale; double *coeff; } spatial; int determine_background(fitsimage *img,spatial *bg,int gx,int gy,int order); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/kernel.h0000644000175000017500000001264612771247463013521 0ustar apalapal/*****************************************************************************/ /* kernel.h */ /*****************************************************************************/ #ifndef __FITSH_KERNEL_H_INCLUDED #define __FITSH_KERNEL_H_INCLUDED 1 /*****************************************************************************/ #define KERNEL_UNKNOWN 0 #define KERNEL_BACKGROUND 1 #define KERNEL_IDENTITY 2 #define KERNEL_GAUSSIAN 3 #define KERNEL_DDELTA 4 /*****************************************************************************/ typedef struct { int type; /* 0: unknown (hsize, image and offset used) */ /* 1: background */ /* 2: identity */ /* 3: Gaussian (hsize, image and offset are */ /* used; sigma, bx, by: parameters */ /* 4: double-delta (hsize and image don't */ /* have to be used, offset is used, para- */ /* meters: bx,by */ double sigma; /* sigma, bx, by: the parameters of the */ int bx,by; /* theoretical kernel (used only in real */ /* gaussian kernels, to describe them, not */ /* used during the convolution */ /* if type==4, kernel is equivalent to */ /* - image[hsize ][hsize ]=-0.5, */ /* - image[hsize+by][hsize+bx]=+0.5 */ int hsize; /* The half width/height of the kernel, the */ /* real width/height is 2*hsize+1 pixels. */ double **image; /* Array of (2*hsize+1)*(2*hsize+1) doubles: */ /* the kernel if type==0 or 3 */ double offset; /* After convolution, the sum should be inc- */ /* reased with this value (if type==0 or 3) */ /* (note that all other kernels can be desc- */ /* ribed with image/offset also, but the co- */ /* nvolution function convolve_point() is */ /* optimized for these types... */ int order; /* Order of spatial variation. */ double *coeff; /* Polynomial coefficients of the variation, */ /* a dynamically allocated array by */ /* fit_kernel_coefficients_*() with a size */ /* of (order+1)*(order+2)/2, obviously... */ int flag; /* A flag, for any kind of usage... */ /* Actually, is used to flag whether the */ /* given kernel should be */ /* - totally ignored (<0), */ /* - taken as a fitted kernel (=0), or */ /* - mark for fitting (>0). */ /* These values are determined after reading */ /* the kernel lists (-k, -ik), and partially */ /* exported (see the switch -ok) if desired. */ int target; /* target flag for the convolution: */ /* 0: reference should be convolved, */ /* !0: image should be convolved. */ } kernel; typedef struct { kernel *kernels; /* List of the kernels. */ int nkernel; /* Number of kernels. */ double ox,oy,scale; /* Shift & scale of the poly- */ /* nomial coefficients. */ int type; /* The type of the kernel set: */ /* 0: not fitted */ /* !0: fitted, polynomial var. */ /* (coeffs stored at kernels) */ } kernellist; typedef struct /* Stamp area: */ { int x1,y1; /* x1 <= x < x2, */ int x2,y2; /* y1 <= y < y2; */ } rectan; /*****************************************************************************/ int kernel_set_verbosity(int vlevel); /*****************************************************************************/ double hermite(int n,double x); double monom(int n,double x); double eval_gaussian(kernel *k,double u,double v); int kernel_image_norm(kernel *k,double sum); int kernel_image_calc_gaussian(kernel *k); int kernel_image_calc_linear(kernel *k); int kernel_image_subtract(kernel *k,kernel *subk); double convolve_point(fitsimage *img,kernel *k,int x,int y); int convolve_image(fitsimage *img,char **mask,kernel *k,fitsimage *out); int fit_kernel_poly_coefficients_block(fitsimage *refimg,fitsimage *img, char **mask,double **weight,int nbx,int nby,kernellist *klist,kernellist *xlist); int fit_kernel_poly_coefficients_stamp(fitsimage *refimg,fitsimage *img, char **mask,double **weight,rectan *rects,int nrect,kernellist *klist,kernellist *xlist); int convolve_with_kernel_set(fitsimage *refimg, char **mask,kernellist *klist,fitsimage *outimg); int convolve_to_subtracted(fitsimage *ref,fitsimage *img,char **mask, kernellist *klist,kernellist *xlist,fitsimage *outimg); /*****************************************************************************/ kernel* add_kernel_empty(kernellist *kl); int add_kernel_gaussian(kernellist *kl,double sigma,int hx,int hy,int hsize,int sporder); int add_kernel_gaussian_set(kernellist *kl,double sigma,int order,int hsize,int sporder); int add_kernel_background(kernellist *kl,int sporder); int add_kernel_identity(kernellist *kl,int sporder); int add_kernel_linear(kernellist *kl,int px,int py,int sporder); int add_kernel_linear_set(kernellist *kl,int ksize,int sporder); int kernel_init_images(kernellist *kl); int create_kernels_from_kernelarg(char *kernelarg,kernellist *kl); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int dump_kernel(FILE *fw,kernel *k); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int kernel_info_dump_image(FILE *fw,kernel *k,int is_comment); int kernel_info_write(FILE *fw,kernellist *kl); int kernel_info_read(FILE *fr,kernellist *kl); /*****************************************************************************/ #endif fitsh-0.9.2/src/weight.h0000644000175000017500000000252111236250260013477 0ustar apalapal/*****************************************************************************/ /* weight.h */ /*****************************************************************************/ #ifndef __WEIGHT_H_INCLUDED #define __WEIGHT_H_INCLUDED 1 #include #include "stars.h" #include "psf.h" /*****************************************************************************/ typedef struct { double x,y; int ix,iy; double flux; double **iarr; } weight; typedef struct { double ***zdata; weight *weights; int nweight; int hsize,grid; } weightlist; /* weight-star.c */ /*********************************************************/ int weight_draw(weightlist *wl,star *stars,int nstar, int hsize,int grid,psf *tpd); /* weight-io.c */ /***********************************************************/ fits * weight_fits_create(weightlist *wl); int weight_parse_fits(fits *img,weightlist *wl); /* weight-gen.c */ /**********************************************************/ int weight_sort(weightlist *wl); weight *weight_get_closest(weightlist *wl,double x0,double y0); int weight_get_intersec_list(weightlist *wl,int x0,int y0,int sx,int sy, int *list,int maxcnt); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/fiarith.c0000644000175000017500000011025412771772035013652 0ustar apalapal/*****************************************************************************/ /* fiarith.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line user interface for basic arithmetics on FITS images. */ /*****************************************************************************/ #define FITSH_FIARITH_VERSION "1.0pre3" /*****************************************************************************/ #include #include #include #include #include #include #include #include "fitsh.h" #include "math/spline/biquad.h" #include "math/dft/pbfft.h" #include "fitsmask.h" #include "psn/psn-general.h" #include "io/iof.h" #include "io/scanarg.h" #include "history.h" #include "longhelp.h" #include "imgtrans.h" #include "common.h" #include "tensor.h" /*****************************************************************************/ typedef struct { char filename[240]; char symname[12]; fits *img; int is_read; } operand; typedef struct { int sx,sy; /* size of the (target) image(s) */ operand *ops; /* set of image operands */ int nop; /* number of image operands */ psn **udfs; /* set of user-defined functions */ int nudf; /* number of user-def. functions */ fits *hdrsave; /* output will inherit this hdr! */ char **mask; } evaldata; /*****************************************************************************/ #define IO_ADD 1 /* + */ #define IO_SUB 2 /* - */ #define IO_MUL 3 /* * */ #define IO_DIV 4 /* / */ #define IO_CHS 6 /* change sign, unary variant of '-' */ #define IF_MIN 32 #define IF_MAX 33 #define IF_MEA 34 #define IF_ABS 36 #define IF_SQRT 37 #define IF_SQ 38 #define IF_NORM 39 #define IF_SIGN 40 #define IF_THETA 41 #define IF_LAP 56 #define IF_SCT 57 #define IF_SMT 58 #define IF_WGH 59 #define IF_CORR 60 #define UDF_OFFSET 64 psnsym psn_subimg_var[] = { { T_VAR, 0, "x", 0 }, { T_VAR, 1, "y", 0 }, { T_VAR, 2, "X", 0 }, { T_VAR, 3, "Y", 0 }, { T_VAR, 4, "a", 0 }, { T_VAR, 5, "b", 0 }, { T_VAR, 6, "c", 0 }, { T_VAR, 7, "d", 0 }, { T_VAR, 8, "e", 0 }, { T_VAR, 9, "f", 0 }, { T_VAR,10, "g", 0 }, { T_VAR,11, "h", 0 }, { 0,0,NULL,0 } }; psnsym psn_img_op[] = { { T_OP, IO_ADD, "+", TO_INFIX }, { T_OP, 0 , "+", TO_PREFIX }, { T_OP, IO_SUB, "-", TO_INFIX }, { T_OP, IO_CHS, "-", TO_PREFIX }, { T_OP, IO_MUL, "*", TO_INFIX }, { T_OP, IO_DIV, "/", TO_INFIX }, {0,0,NULL,0} }; psnsym psn_img_fn[] = { { T_FN, IF_MIN, "min" , -1 }, { T_FN, IF_MAX, "max" , -1 }, { T_FN, IF_MEA, "mean" , -1 }, { T_FN, IF_ABS, "abs" , 1 }, { T_FN, IF_SIGN,"sign" , 1 }, { T_FN, IF_THETA,"theta" , 1 }, { T_FN, IF_NORM, "norm" , 1 }, { T_FN, IF_SQRT,"sqrt" , 1 }, { T_FN, IF_SQ, "sq" , 1 }, { T_FN, IF_LAP, "laplace", 1 }, { T_FN, IF_SCT, "scatter", 1 }, { T_FN, IF_SMT, "smooth" , 3 }, { T_FN, IF_WGH, "weight" , 3 }, { T_FN, IF_CORR,"corr" , 2 }, { 0,0,NULL,0 } }; psnprop psn_img_prop[] = { { IO_ADD, 2, 20, ASSOC_LEFT }, { IO_SUB, 2, 20, ASSOC_LEFT }, { IO_MUL, 2, 21, ASSOC_LEFT }, { IO_DIV, 2, 21, ASSOC_LEFT }, { IO_CHS, 1, 22 }, { IF_MIN, -1, 0 }, { IF_MAX, -1, 0 }, { IF_MEA, -1, 0 }, { IF_ABS, 1, 0 }, { IF_SIGN, 1, 0 }, { IF_THETA,1, 0 }, { IF_NORM, 1, 0 }, { IF_SQRT, 1, 0 }, { IF_SQ, 1, 0 }, { IF_LAP, 1, 0 }, { IF_SCT, 1, 0 }, { IF_SMT, 3, 0 }, { IF_WGH, 3, 0 }, { IF_CORR, 2, 0 }, { 0, 0, 0,0 } }; /*****************************************************************************/ char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ typedef struct { fits *img; double val; } imgstack; /*****************************************************************************/ fits *newimage_empty(evaldata *ed) { fits *img; img=fits_create(); fits_alloc_image(img,ed->sx,ed->sy); fits_set_header_boolean(img,"SIMPLE",FITS_SH_FIRST,1,"Fits standard"); fits_set_header_integer(img,"BITPIX",FITS_SH_FIRST,-32,NULL); fits_set_header_integer(img,"NAXIS",FITS_SH_FIRST,2,NULL); fits_set_header_integer(img,"NAXIS1",FITS_SH_FIRST,ed->sx,NULL); fits_set_header_integer(img,"NAXIS2",FITS_SH_FIRST,ed->sy,NULL); img->i.bit=-32; img->i.curr.bscale=1.0; img->i.curr.bzero=0.0; img->i.read.bscale=1.0; img->i.read.bzero=0.0; return(img); } fits *newimage(evaldata *ed,double d) { fits *img; int i,j; img=newimage_empty(ed); for ( i=0 ; ii.sy ; i++ ) { for ( j=0 ; ji.sx ; j++ ) { img->i.data[i][j]=d; } } return(img); } /*****************************************************************************/ int scatter(fits *img) { double **bqc; int i,j,sx,sy; sx=img->i.sx, sy=img->i.sy; bqc=(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); biquad_coeff(img->i.data,sx,sy,bqc,NULL); for ( i=0 ; ii.data[i][j]=biquad_scatter(bqc,j,i); } } tensor_free(bqc); return(0); } /*****************************************************************************/ int evaluate_min(imgstack *stack,int narg,int sx,int sy) { int i,j,k; double w,c; fits *img; if ( narg <= 0 ) { stack[0].img=NULL;stack[0].val=0.0;return(0); } for ( k=0,img=NULL ; ki.data[i][j]; else c=stack[k].val; if ( k==0 ) w=c; else if ( ci.data[i][j]=w; } } for ( k=0 ; kw ) w=stack[k].val; } stack[0].val=w; return(0); } for ( i=0,w=0.0 ; ii.data[i][j]; else c=stack[k].val; if ( k==0 ) w=c; else if ( c>w ) w=c; } img->i.data[i][j]=w; } } for ( k=0 ; ki.data[i][j]; else c=stack[k].val; w+=c; } img->i.data[i][j]=w*div; } } for ( k=0 ; kimg==NULL ) return(0); /* nothing to be done */ hsize=(int)dhsize; if ( hsize<=0 ) return(0); fsize=2*hsize+1; kernel=tensor_alloc_2d(double,fsize,fsize); km=1.0/(sqrt(2.0)*sigma); for ( i=-hsize ; i<=hsize ; i++ ) { y0=km*((double)i-0.5); y1=km*((double)i+0.5); for ( j=-hsize ; j<=hsize ; j++ ) { x0=km*((double)j-0.5); x1=km*((double)j+0.5); kernel[i+hsize][j+hsize]=(erf(x1)-erf(x0))*(erf(y1)-erf(y0)); } } sum=0.0; for ( i=0 ; iimg; sx=ed->sx, sy=ed->sy; nmask=fits_mask_expand_false(ed->mask,sx,sy,hsize,-1,-1,1); nimg=fits_duplicate(img); for ( i=0 ; imask[i][j] ) nimg->i.data[i][j]=0.0; continue; } w=0.0; for ( k=-hsize ; k<=hsize ; k++ ) { for ( l=-hsize ; l<=hsize ; l++ ) { w+=img->i.data[i-k][j-l]* kernel[hsize+k][hsize+l]; } } nimg->i.data[i][j]=w; } } fits_mask_free(ed->mask); ed->mask=nmask; fits_free(img); stack->img=nimg; tensor_free(kernel); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int evaluate_weight(evaldata *ed,imgstack *simg,imgstack *swgh,double dbsize) { int bsize,sx,sy,i,j,bx,by,k,l; fits *img,*wgh; double sm,ii,iw,sw; /* nothing to be done if any of the images (target image and/or weight) */ /* are constant, so (imgstack *)->img == NULL (no associated FITS image): */ if ( simg->img==NULL || swgh->img==NULL ) return(0); sx=ed->sx, sy=ed->sy; img=simg->img; wgh=swgh->img; bsize=(int)dbsize; /* if block size is less than or equal to 1, do nothing. */ if ( bsize<=1 ) return(0); for ( i=0 ; isy ) by=sy-i; for ( j=0 ; jsx ) bx=sx-j; sm=sw=0.0; for ( k=0 ; ki.data[i+k][j+l]; iw=wgh->i.data[i+k][j+l]; sm+=(ii-iw); sw+=iw; } } if ( sw<=0.0 ) continue; sm=sm/(double)(bx*by); for ( k=0 ; ki.data[i+k][j+l]; img->i.data[i+k][j+l] = iw+sm; } } } } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int evaluate_correlation(evaldata *ed,imgstack *s1,imgstack *s2) { int sx,sy,i,j; double val; if ( s1->img==NULL && s2->img==NULL ) { s1->val = s1->val * s2->val; return(0); } else if ( s1->img==NULL || s2->img==NULL ) { if ( s1->img != NULL ) { s2->img=s1->img; s1->val=s2->val; s1->img=NULL; } sx=ed->sx, sy=ed->sy; val=0.0; for ( i=0 ; iimg->i.data[i][j]; } } s1->val = s1->val * val; return(0); } else { complex **c1,**c2,*c,w; fitsimage *i1,*i2; double norm; i1=&s1->img->i; i2=&s2->img->i; sx=ed->sx; sy=ed->sy; c1=tensor_alloc_2d(complex,sx,sy); c2=tensor_alloc_2d(complex,sx,sy); c =tensor_alloc_1d(complex,sy); for ( i=0 ; idata[i][j]; c1[i][j].im=0.0; c2[i][j].re=i2->data[i][j]; c2[i][j].im=0.0; } pbfft_conv(c1[i],sx,0); pbfft_conv(c2[i],sx,0); } for ( j=0 ; jdata[i][j]=norm*w.re; } } tensor_free(c); tensor_free(c2); tensor_free(c1); return(0); } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ fits *evaluate(evaldata *ed,psn *pseq,int hid) { FILE *fr; imgstack stack[32]; fits *img; psnterm *seq; int i,j,k,sp,sx,sy,udfid,narg,iac; psn *udf; double uvars[16],res,crc,w; sx=ed->sx, sy=ed->sy; sp=0;ed->hdrsave=NULL; for ( seq=pseq->terms ; seq->type ; seq++ ) { narg=seq->minor; switch( seq->type ) { case T_CONST: stack[sp].img=NULL; stack[sp].val=pseq->cons[seq->major]; sp++; break; case T_SCONST: stack[sp].img=NULL; stack[sp].val=(double)(seq->major); sp++; break; case T_VAR: k=seq->major; if ( ed->ops[k].is_read ) { img=ed->ops[k].img; } else { fr=fopen(ed->ops[k].filename,"rb"); img=fits_read(fr); fits_rescale(img); fclose(fr); } if ( k==hid ) { ed->hdrsave=fits_create(); fits_copy_full_header(ed->hdrsave,img); } stack[sp].img=img; stack[sp].val=0.0; sp++; break; case T_OP: case T_FN: switch ( seq->major ) { case IO_ADD: if ( stack[sp-2].img!=NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]+= stack[sp-1].img->i.data[i][j]; } } fits_free(stack[sp-1].img); } else if ( stack[sp-2].img==NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]+=stack[sp-2].val; } } stack[sp-2].img=stack[sp-1].img; } else if ( stack[sp-2].img!=NULL && stack[sp-1].img==NULL ) { for ( i=0 ; ii.data[i][j]+=stack[sp-1].val; } } } else { stack[sp-2].val += stack[sp-1].val; } sp--; break; case IO_SUB: if ( stack[sp-2].img!=NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]-= stack[sp-1].img->i.data[i][j]; } } fits_free(stack[sp-1].img); } else if ( stack[sp-2].img==NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]=stack[sp-2].val-stack[sp-1].img->i.data[i][j]; } } stack[sp-2].img=stack[sp-1].img; } else if ( stack[sp-2].img!=NULL && stack[sp-1].img==NULL ) { for ( i=0 ; ii.data[i][j]-=stack[sp-1].val; } } } else { stack[sp-2].val -= stack[sp-1].val; } sp--; break; case IO_MUL: if ( stack[sp-2].img!=NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]*= stack[sp-1].img->i.data[i][j]; } } fits_free(stack[sp-1].img); } else if ( stack[sp-2].img==NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]*=stack[sp-2].val; } } stack[sp-2].img=stack[sp-1].img; } else if ( stack[sp-2].img!=NULL && stack[sp-1].img==NULL ) { for ( i=0 ; ii.data[i][j]*=stack[sp-1].val; } } } else { stack[sp-2].val *= stack[sp-1].val; } sp--; break; case IO_DIV: if ( stack[sp-2].img!=NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]; if ( w != 0.0 ) stack[sp-2].img->i.data[i][j]/=w; else stack[sp-2].img->i.data[i][j]=0.0; } } fits_free(stack[sp-1].img); } else if ( stack[sp-2].img==NULL && stack[sp-1].img!=NULL ) { for ( i=0 ; ii.data[i][j]; if ( w != 0.0 ) stack[sp-1].img->i.data[i][j]=stack[sp-2].val/w; else stack[sp-1].img->i.data[i][j]=0.0; } } stack[sp-2].img=stack[sp-1].img; } else if ( stack[sp-2].img!=NULL && stack[sp-1].img==NULL ) { for ( i=0 ; ii.data[i][j]/=stack[sp-1].val; } } } else { stack[sp-2].val /= stack[sp-1].val; } sp--; break; case IO_CHS: if ( stack[sp-1].img != NULL ) { for ( i=0 ; ii.data[i][j]=-stack[sp-1].img->i.data[i][j]; } } else { stack[sp-1].val=-stack[sp-1].val; } break; case IF_MIN: evaluate_min(&stack[sp-narg],narg,sx,sy); sp+=1-narg; break; case IF_MAX: evaluate_max(&stack[sp-narg],narg,sx,sy); sp+=1-narg; break; case IF_MEA: evaluate_mean(&stack[sp-narg],narg,sx,sy); break; case IF_ABS: if ( stack[sp-1].img != NULL ) { for ( i=0 ; ii.data[i][j]=fabs(stack[sp-1].img->i.data[i][j]); } } else stack[sp-1].val=fabs(stack[sp-1].val); break; case IF_SIGN: if ( stack[sp-1].img != NULL ) { for ( i=0 ; ii.data[i][j]; stack[sp-1].img->i.data[i][j]=(d<0?-1.0:d>0?+1.0:0.0); } } } else { double d; d=stack[sp-1].val; stack[sp-1].val=(d<0?-1.0:d>0?+1.0:0.0); } break; case IF_THETA: if ( stack[sp-1].img != NULL ) { for ( i=0 ; ii.data[i][j]; stack[sp-1].img->i.data[i][j]=(d<0?-1.0:+1.0); } } } else { double d; d=stack[sp-1].val; stack[sp-1].val=(d<0?-1.0:+1.0); } break; case IF_NORM: if ( stack[sp-1].img != NULL ) { double norm,n; norm=0.0,n=0.0; for ( i=0 ; ii.data[i][j]); n += 1.0; } } fits_free(stack[sp-1].img); stack[sp-1].img=NULL; stack[sp-1].val=norm/n; } else stack[sp-1].val=fabs(stack[sp-1].val); break; case IF_SQRT: if ( stack[sp-1].img != NULL ) { double d; for ( i=0 ; ii.data[i][j]; if ( d>0.0 ) d=sqrt(d); else d=0.0; stack[sp-1].img->i.data[i][j]=d; } } } else { double d; d=stack[sp-1].val; if ( d>0.0 ) d=sqrt(d); else d=0.0; stack[sp-1].val=d; } break; case IF_SQ: if ( stack[sp-1].img != NULL ) { double d; for ( i=0 ; ii.data[i][j]; stack[sp-1].img->i.data[i][j]=d*d; } } } else { double d; d=stack[sp-1].val; stack[sp-1].val=d*d; } break; case IF_LAP: if ( stack[sp-1].img != NULL ) cyclic_laplace_of_image(&stack[sp-1].img->i); else stack[sp-1].val=0.0; break; case IF_SCT: if ( stack[sp-1].img != NULL ) scatter(stack[sp-1].img); else stack[sp-1].val=0.0; break; case IF_SMT: evaluate_smooth(ed,&stack[sp-3],stack[sp-2].val,stack[sp-1].val); if ( stack[sp-2].img != NULL ) fits_free(stack[sp-2].img); if ( stack[sp-1].img != NULL ) fits_free(stack[sp-1].img); sp+=1-3; break; case IF_WGH: evaluate_weight(ed,&stack[sp-3],&stack[sp-2],stack[sp-1].val); if ( stack[sp-2].img != NULL ) fits_free(stack[sp-2].img); if ( stack[sp-1].img != NULL ) fits_free(stack[sp-1].img); sp+=1-3; break; case IF_CORR: evaluate_correlation(ed,&stack[sp-2],&stack[sp-1]); if ( stack[sp-1].img != NULL ) fits_free(stack[sp-1].img); sp+=1-2; break; default : if ( seq->major < UDF_OFFSET ) break; udfid=seq->major-UDF_OFFSET; udf=ed->udfs[udfid]; narg=seq->minor; img=newimage(ed,0.0); iac=-1;crc=0.0; for ( i=0 ; ii.data[i][j]; else uvars[4+k]=stack[sp-narg+k].val; } k=psn_double_calc(udf,psn_general_funct,&res,uvars); if ( k ) res=0.0; if ( iac<0 ) crc=res,iac=0; else if ( ! iac && crc != res ) iac=1; img->i.data[i][j]=res; } } for ( k=0 ; k\" [-o|--output ] \n" "\t[-b|--bitpix ] [-e|--header ]\n" "\t[-D|--data bitpix=,bscale=,bzero=|]\n" "\t[-M|--input-mask [-im <...>]] [--output-mask ]\n" "\t[-s|--size ] [-a|--apply-mask]\n"); fprintf(fw, "Available image operators:\n" "\t+, -, *, /.\n"); fprintf(fw, "Available image functions:\n" "\tmin(...), max(...), mean(...), abs(.), sqrt(.), sq(.),\n" "\tsign(.), theta(.),\n" "\tlaplace(.), scatter(.), corr(.,.), \n" "\tsmooth(.,,), weight(.,.,).\n"); fprintf(fw, "Available general operators and functions: see ./src/psn/psn-general.[ch]\n"); return(0); } longhelp_entry fiarith_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-o, --output ", "The name of the output file (omitting or specifing '-' yields the " "output to be written to stdout)." }, { "-s, --size ,", "Horizontal and vertical size of the output image (meaningless " "if contains any existing FITS image)." }, { "-M, --input-mask ", "Input mask file to co-add to output image." }, { "--output-mask ", "Name of output mask file to create." }, { "-D, --data ", "Output pixel data format specification." }, { "-b, --bitpix ", "Standard FITS output bitpix value." }, { "-a, --apply-mask", "Resets pixel values to zero if masked." }, { "-e, --header ", "Inherit output header from the specified FITS file." }, { "Available arithmetic operators:", NULL }, { "+", "Addition." }, { "-", "Subtraction." }, { "*", "Multiplication." }, { "/", "Division. Dividing by zero yields zero automatically." }, { "Available arithmetic functions:", NULL }, { "sin(.), cos(.), tan(.)", "Trigonometric functions." }, { "asin(.), acos(.), atan(.), atan2(.,.), arg(.,.)", "Inverse trigonometric functions." }, { "abs(.), sq(.), sqrt(.), exp(.), log(.)", "Absolute value, square, Square root, exponential and natural logarithm functions." }, { "Available image functions:", NULL }, { "min(....)", "The per pixel minimal value of pixel intensities of the images " "listed (separated by comma) in the argument of the function." }, { "max(....)", "The per pixel maximal value of pixel intensities of the images " "listed (separated by comma) in the argument of the function." }, { "mean(...)", "The per pixel mean value of pixel intensities of the images " "listed (separated by comma) in the argument of the function." }, { "norm(.)", "The mean of the pixel values on the image." }, { "sign(.)", "The per pixel sign function." }, { "theta(.)", "The per pixel Heaviside step function." }, { "laplace(.)", "The Laplace transform of the image." }, { "scatter(.)", "Noise level estimation for the image." }, { "corr(.,.)", "Correlation between two images." }, { "smooth(,,)", "The smoothed variant of the first argument (threated as an image), " "which is yielded by the convolution with a Gaussian profile with a " "standard deviation of , evaluated on a kernel stamp " "with the size of ." }, { "Examples:",NULL }, { "fiarith \"'img1.fits'-'orig.fits'\" -o diff.fits", "Calculates the per pixel difference between images \"img1.fits\" " "and \"orig.fits\" and stores the result in \"diff.fits\"." }, { "fiarith -s 512,512 \"137.42\" -o constant.fits", "Creates a new image with the size of 512 by 512 pixels with the constant " "value of 137.42." }, { "fiarith \"'-'*26\" -o -", "Multiplies the pixel intensities of the image read from the standard " "input by 26 and writes the result to the standard output. The \"-o -\" can " "either be omitted, since by default the output is written to stdout." }, { "fiarith -s 512,512 \"['input.fits'](a/(1-0.3*(X^2-Y^2)))\" -o flattened.fits", "This invocation evaluates the \"a/(1-0.3*(X^2+Y^2))\" expression " "on each pixel of the image \"input.fits\", where \"a\" referes to the " "pixel value itself and X and Y are the normalized spatial coordinates. " "The normalization is always done as X=(2*x-SX)/(SX) and Y=(2*y-SY)/SX, " "i.e. the X and Y coordinates are zero at the center of the images, X has " "a unity absolute value at the left and right edges and Y is scaled " "properly to X." }, { "fiarith \"('R.fits'-'B.fits'-0.5*'D.fits')*(norm('F.fits')/'F.fits')\" -o C.fits", "This operation performs a simple bias, dark and flat calibration on the " "input raw image \"R.fits\", expecting \"B.fits\", \"D.fits\" and " "\"F.fits\" to be the master bias, dark and flat calibration frames, " "respectively; and assuming an exposure time for the raw image which is " "the half of the exposure time of the master dark frame. " "Due to the \"norm(...)\" function, the mean intensity level of the image " "is kept to be the same as it is in the raw image." }, { NULL,NULL } }; int fprint_fiarith_long_help(FILE *fw,int is_wiki) { char *synopsis= "fiarith [options] \"\" [-o|--output ]"; char *description= "The purpose of this program is to evaluate which is " "intented to contain arithmetic operations and functions on FITS " "images (of the same size). See the section \"Examples\" below " "for examples on the syntax of "; fprint_generic_long_help(fw,is_wiki,fiarith_long_help,synopsis,description); return(0); } int main(int argc,char *argv[]) { fits *img; FILE *fr,*fw; char *headerfile,*outfile,**inmasklist,*outmaskname,*fdpstring; int i,j,headeropid,nsx,nsy,apply_mask; char *expr,name[256],buff[256]; psnsym *mysyms[5],*myfunctsyms[4],*csym,*udfsym; psn *w,*pexpr; evaldata ed_data,*ed=&ed_data; int is_help; fitsdataparam fdp; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; outmaskname=headerfile=outfile=NULL;expr=NULL; inmasklist=NULL;nsx=nsy=0;apply_mask=0;is_help=0; fdpstring=NULL; fdp.bitpix=-32;fdp.is_scale=0;fdp.bscale=1.0;fdp.nquantizebit=0; i=scanarg(argc,argv,SCANARG_WILDCARD_DASH, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help|--short-help|--help-short:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-o|--output:%s",&outfile, "-e|--header:%s",&headerfile, "-b|--bitpix:%d",&fdp.bitpix, "-D|--data:%s",&fdpstring, "-s|--size:%d,%d",&nsx,&nsy, "-M|--input-mask:%t",&inmasklist, "--output-mask:%s",&outmaskname, "-a|--apply-mask:%f",&apply_mask, "-[a-zA-Z]|--*:%e", "*:%a",&expr, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fiarith",FITSH_FIARITH_VERSION,is_help); return(0); } else if ( 1nop =0,ed->ops =NULL; ed->nudf=0;ed->udfs=NULL; headeropid=-1;ed->mask=NULL; udfsym=NULL; myfunctsyms[0]=psn_subimg_var; myfunctsyms[1]=psn_general_op; myfunctsyms[2]=psn_general_fn; myfunctsyms[3]=NULL; for ( i=0 ; ii.dim != 2 ) { fprint_error("file '%s' has invalid header",name); return(1); } } else { img=fits_read(fr); if ( img==NULL || img->i.dim != 2 ) { fprint_error("unable to read data from file '%s'",name); return(1); } fits_rescale(img); } fclose(fr); if ( ed->nop==0 ) { ed->ops=(operand *)malloc(sizeof(operand)); ed->sx=img->i.sx, ed->sy=img->i.sy; ed->mask=fits_mask_read_from_header(&img->header,ed->sx,ed->sy,NULL); fits_mask_mark_nans(&img->i,ed->mask,MASK_NAN); } else { ed->ops=(operand *)realloc(ed->ops,sizeof(operand)*(ed->nop+1)); if ( ed->sx != img->i.sx || ed->sy != img->i.sy ) { fprintf(stderr,"File '%s' has different size (not %dx%d), exiting.\n",name,ed->sx,ed->sy); exit(1); } fits_mask_mask_from_header(ed->mask,&img->header,ed->sx,ed->sy,NULL); } imgid=ed->nop+1; sprintf(buff,"img%d",imgid); strcpy(ed->ops[ed->nop].symname,buff); strcpy(ed->ops[ed->nop].filename,name); ed->ops[ed->nop].img=img; ed->ops[ed->nop].is_read=is_read; memmove(expr+j,expr+i,strlen(expr+i)+1); memmove(expr+j+strlen(buff),expr+j,strlen(expr+j)+1); memcpy(expr+j,buff,strlen(buff)); i=j+strlen(buff); ed->nop++; if ( headerfile != NULL ) { if ( strcmp(name,headerfile)==0 ) headeropid=ed->nop-1; } } else if ( expr[i]=='[' ) { int j,k,l,m,n,level; j=i;i++;level=1;n=1; for ( k=0 ; iudfs=(psn **)realloc(ed->udfs,sizeof(psn *)*(ed->nudf+1)); ed->udfs[ed->nudf]=pexpr; sprintf(name,"udf%d",ed->nudf+1); m=strlen(name); l=strlen(expr); expr=(char *)realloc(expr,l+m+1); memmove(expr+j+m,expr+j,l-j+1); memcpy(expr+j,name,m); i=j; k=ed->nudf; udfsym=(psnsym *)realloc(udfsym,sizeof(psnsym)*(k+2)); udfsym[k].type=T_FN; udfsym[k].major=UDF_OFFSET+k; udfsym[k].name=(char *)malloc(m+1); strcpy(udfsym[k].name,name); udfsym[k].minor=n; ed->nudf++; } else { i++; continue; } } if ( udfsym != NULL ) { udfsym[ed->nudf].type=0; udfsym[ed->nudf].major=0; udfsym[ed->nudf].name=NULL; udfsym[ed->nudf].minor=0; } if ( ed->nop==0 ) { ed->sx=nsx,ed->sy=nsy; if ( ed->sx<=0 || ed->sy<=0 ) { fprint_error("unexpected or invalid image size"); return(1); } } if ( ed->mask==NULL ) { ed->mask=fits_mask_create_empty(ed->sx,ed->sy); } if ( inmasklist != NULL ) { if ( join_masks_from_files(ed->mask,ed->sx,ed->sy,inmasklist) ) { fprint_error("unable to read one of the input masks"); return(1); } } if ( headerfile != NULL && headeropid<0 ) { fprintf(stderr,"Warning: file specified after -e not found in the expression, the\n"); fprintf(stderr," header of the output may not contain the expected information!\n"); } csym=(psnsym *)malloc(sizeof(psnsym)*(ed->nop+1)); for ( i=0 ; inop ; i++ ) { csym[i].type=T_VAR; csym[i].major=i; csym[i].name=ed->ops[i].symname; } csym[ed->nop].type=0; csym[ed->nop].major=0; csym[ed->nop].name=NULL; csym[ed->nop].minor=0; mysyms[0]=psn_img_op; mysyms[1]=psn_img_fn; mysyms[2]=csym; if ( udfsym != NULL ) { mysyms[3]=udfsym; mysyms[4]=NULL; } else mysyms[3]=NULL; w=psn_conv_string(expr,mysyms); if ( w==NULL ) { fprint_error("arithmetic expression: symbolic error"); return(1); } psn_init(w,psn_img_prop); pexpr=psn_conv(w,psn_img_prop); psn_free(w); if ( pexpr==NULL || psn_test(pexpr) ) { fprint_error("arithmetic expression: parse error"); return(1); } img=evaluate(ed,pexpr,headeropid); psn_free(pexpr); img->i.bit=fdp.bitpix; img->i.curr.bscale=1.0; img->i.curr.bzero=0.0; if ( fdp.is_scale ) img->i.read.bscale=fdp.bscale,img->i.read.bzero=fdp.bzero; else if ( img->i.bit<0 ) img->i.read.bscale=1.0,img->i.read.bzero=0.0; else img->i.read.bscale=1.0,img->i.read.bzero=(1<<(img->i.bit-1)); if ( ed->hdrsave != NULL ) fits_copy_full_header(img,ed->hdrsave); fits_set_image_params(img); /* mask=fits_mask_create_floyd(img,ed->sx,ed->sy,1,100); */ /* for testing */ fits_history_export_command_line(img,"fiarith",FITSH_FIARITH_VERSION,argc,argv); fits_backscale(img,img->i.read.bscale,img->i.read.bzero); mark_integerlimited_pixels(&img->i,ed->mask,img->i.bit,1,MASK_OVERSATURATED,MASK_OVERSATURATED); fits_mask_export_as_header(&img->header,1,ed->mask,ed->sx,ed->sy,NULL); for ( i=0 ; isy && apply_mask ; i++ ) { for ( j=0 ; jsx ; j++ ) { if ( ed->mask[i][j] ) img->i.data[i][j]=0.0; } } if ( fdp.nquantizebit>0 ) fits_image_quantize(&img->i,fdp.nquantizebit); if ( outfile==NULL ) fw=stdout; else fw=fopenwrite(outfile); if ( fw==NULL ) { fprint_error("unable to create output image"); return(1); } fits_write(fw,img); fclosewrite(fw); if ( outmaskname != NULL ) { fw=fopenwrite(outmaskname); if ( fw==NULL ) { fprint_error("unable to create output mask file"); return(1); } fits_write_header(fw,img); fclosewrite(fw); } fits_free(img); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/maskdraw.h0000644000175000017500000000113011224376620014022 0ustar apalapal/*****************************************************************************/ /* maskdraw.h */ /*****************************************************************************/ #ifndef __MASKDRAW_H_INCLUDED #define __MASKDRAW_H_INCLUDED 1 /*****************************************************************************/ int maskdraw_parse_and_draw(char **mask,int sx,int sy,char *maskblock); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/star-cand-lnk.c0000644000175000017500000001354012771247614014662 0ustar apalapal/*****************************************************************************/ /* star-cand-lnk.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Star candidate searching based on the `uplink` algorithm... */ /*****************************************************************************/ #include #include #include #include #include #include "io/iof.h" #include "fitsmask.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/point.h" #include "math/tpoint.h" #include "math/delaunay.h" #include "link/linkpoint.h" #include "statistics.h" #include "tensor.h" #include "fitsh.h" #include "common.h" #include "stars.h" /*****************************************************************************/ /* this object has been obsoleted by `linkrange`, see linkpoint.[ch]. */ /* typedef struct { int x,y; int nid,nneg; } llpoint; */ /* llpoint_count(): functionality obsoleted by the new linkpoint.c library */ /* int llpoint_count(linkpoint **lparr,llpoint *llpoints,int nipoint) { int n,m,x,y,nx,ny; for ( n=0 ; n=0 ) llpoints[m].nneg++; } return(0); } */ typedef struct { double sbg,sbg2,sfx; int nbg,cindex; } lbackground; int search_star_candidates_link(fitsimage *img,char **mask, candidate **rcands,int *rncand, range *srcrange,double threshold,double fluxthreshold, double critical_prominence) { candidate *cands,*wc; int icand,ncand; int i,j,k,l,m,sx,sy,mx,my; double bg,amp,cx,cy,axx,axy,ayy,peak,flux,noise; linkpoint **lparr; linkreference **lrarr; linkrange lrin,*lr; lbackground *lbgs; sx=img->sx,sy=img->sy; if ( srcrange==NULL ) lr=NULL; else { lrin.xmin=srcrange->xmin,lrin.xmax=srcrange->xmax; lrin.ymin=srcrange->ymin,lrin.ymax=srcrange->ymax; lr=&lrin; } lparr=linkpoint_create(img->data,sx,sy,lr,mask,1); linkpoint_reconnect(lparr,sx,sy); lrarr=linkreference_create(lparr,sx,sy); if ( critical_prominence >= 0.0 ) { for ( i=0 ; i lrarr[i][j].ncnt ) { int nx,ny,n,cmask; cmask=linkpoint_mask_same_group(lparr,sx,sy,j,i); n=linkpoint_local_extreme(img->data,0,0,sx,sy,mask,j,i,+1,cmask,&nx,&ny); if ( n<=0 ) continue; else if ( ! linkpoint_is_same_endpoint(lparr,j,i,nx,ny) ) { lparr[i][j].nx=nx; lparr[i][j].ny=ny; /* fprintf(stderr,"connect (%d,%d)->(%d,%d) [%d,%d]:[%d,%d]\n",j,i,nx,ny,lparr[i][j].mx,lparr[i][j].my,lparr[ny][nx].mx,lparr[ny][nx].my); */ } } } } linkreference_free(lrarr); linkpoint_reconnect(lparr,sx,sy); lrarr=linkreference_create(lparr,sx,sy); } for ( i=0 ; i0 ) { lbgs=(lbackground *)malloc(sizeof(lbackground)*icand); for ( i=0 ; idata[i][j]; if ( lrarr[i][j].nsgndata[i][j]; lbgs[k].sbg2+=img->data[i][j]*img->data[i][j]; lbgs[k].nbg ++; } } } cands=NULL; ncand=0; for ( i=0 ; i0.0 ) noise=sqrt(noise); else noise=0.0; flux=lbgs[k].sfx-lrarr[i][j].mcnt*bg; k=fit_small_parabola_block_param(img,j,i,&cx,&cy,&axx,&axy,&ayy,&peak); if ( k ) continue; /* fprintf(stderr,"bg=%g flux=%g\n",bg,flux); */ amp=peak-bg; if ( amp<0.0 ) continue; else if ( threshold>0.0 && amp0.0 && fluxix=j,wc->cx=cx+(double)j+0.5; wc->iy=i,wc->cy=cy+(double)i+0.5; wc->peak=peak; wc->amp=amp; wc->bg=bg; wc->noise=noise; wc->sxx=-axx/amp; wc->sxy=-axy/amp; wc->syy=-ayy/amp; wc->marked=0; wc->ipoints=(ipoint *)malloc(sizeof(ipoint)*lrarr[i][j].mcnt); wc->nipoint=0; wc->area=(double)lrarr[i][j].mcnt; wc->flux=flux; k=lrarr[i][j].identifier; lbgs[k].cindex=ncand; ncand++; } } for ( i=0 ; iipoints[wc->nipoint].x=j; wc->ipoints[wc->nipoint].y=i; wc->nipoint++; } } if ( rcands != NULL ) *rcands=cands; if ( rncand != NULL ) *rncand=ncand; if ( lbgs != NULL ) free(lbgs); linkreference_free(lrarr); linkpoint_free(lparr); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/star-psf.c0000644000175000017500000001562012771510437013760 0ustar apalapal/*****************************************************************************/ /* star-psf.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to star PSF fitting to a FITS image. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006, Pal, A. (apal@szofi.elte.hu), part of the 'FI' package */ /*****************************************************************************/ #define __STAR_PSF_C 1 #include #include #include #include #include #include "fitsmask.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "link/linkblock.h" #include "tensor.h" #include "fitsh.h" #include "common.h" #include "stars.h" typedef struct { int hsize; int grid; double **bqc; double **bqcdx, **bqcdy; } dcpsf; void psf_2d_exact_xy(void *xpnt,double *a,double *yy,double *dyda,void *p) { double x,y,x0,y0,x1,y1,x2,y2,px1,py1,px2,py2, grid,offs,maxv,i0,ix,iy,is_normal; dcpsf *dp=(dcpsf *)p; x=((ipoint *)xpnt)->x,x0=a[2],x1=x-x0,x2=x1+1.0; y=((ipoint *)xpnt)->y,y0=a[3],y1=y-y0,y2=y1+1.0; grid=(double)dp->grid; offs=0.5+(double)dp->hsize; maxv=grid*2.0*offs; px1=grid*(x1+offs),py1=grid*(y1+offs); px2=grid*(x2+offs),py2=grid*(y2+offs); if ( px1<0.0 ) px1=0.0; if ( px1>maxv) px1=maxv; if ( px2<0.0 ) px2=0.0; if ( px2>maxv) px2=maxv; if ( py1<0.0 ) py1=0.0; if ( py1>maxv) py1=maxv; if ( py2<0.0 ) py2=0.0; if ( py2>maxv) py2=maxv; is_normal=(px1bqc,px1,py1,px2,py2); else i0=0.0; *yy=a[0]*i0+a[1]; if ( dyda != NULL ) { dyda[0]=i0; dyda[1]=1.0; if ( is_normal ) { ix=biquad_isc_int_rectangle(dp->bqcdx,px1,py1,px2,py2), iy=biquad_isc_int_rectangle(dp->bqcdy,px1,py1,px2,py2); } else { ix=0.0, iy=0.0; } dyda[2]=-ix*a[0]*grid; dyda[3]=-iy*a[0]*grid; } } int fit_psf(int nipoint,double *yvals,void **fitpnt,candidate *wc, starlocation *loc,psffit *pfp,psf *tpd) { void (*psf_abxy)(void *,double *,double *,double *,void *); dcpsf dp; int grid,hsize,order,bx,by,nvar; int i,j,k; double ***btarr,**coeff,*cpoly,afp[4],lam,w,sum,ox,oy,scale; psf_abxy=psf_2d_exact_xy; grid =dp.grid =tpd->grid; hsize=dp.hsize=tpd->hsize; order=tpd->order; nvar=(order+1)*(order+2)/2; ox=tpd->ox, oy=tpd->oy, scale=tpd->scale; bx=grid*(2*hsize+1), by=grid*(2*hsize+1); coeff=(double **)tensor_alloc_2d(double,bx,by); btarr=(double ***)tensor_alloc_3d(double,2*bx+1,2*by+1,3); dp.bqc =btarr[0]; dp.bqcdx=btarr[1]; dp.bqcdy=btarr[2]; cpoly=(double *)tensor_alloc_1d(double,nvar); sum=0.0; for ( i=0 ; icoeff[k][i][j]; } w=eval_2d_poly(wc->cx,wc->cy,order,cpoly,ox,oy,scale); coeff[i][j]=w; sum+=w; } } tensor_free(cpoly); w=1.0/sum; for ( i=0 ; iamp*sum; afp[1]=wc->bg; afp[2]=wc->cx; afp[3]=wc->cy; lam=0.001; for ( i=0 ; iiterations ; i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,psf_abxy,4,nipoint,&dp,lam,10.0); /* lin_fit(fitpnt,yvals,afp,NULL,psf_abxy,2,nipoint,&dp,NULL); */ /*!!*/ for ( i=0 ; i %g\n",wc->bg,afp[1]); */ loc->gamp=afp[0]; loc->gbg=afp[1]; loc->gcx=afp[2]; loc->gcy=afp[3]; tensor_free(btarr); tensor_free(coeff); return(0); } int fit_star_psf_native(fitsimage *img,char **mask,candidate *cands,int ncand,star **rstars,int *rnstar,psffit *pfp,psf *tpd) { star *stars,*ws; candidate *wc; int nstar,n,ix,iy,bsize; int i; void **fitpnt; double *yvals; starlocation loc; ipoint *ipoints; if ( rstars != NULL ) *rstars=NULL; if ( rnstar != NULL ) *rnstar=0; if ( ncand == 0 ) return(0); else if ( ncand < 0 ) return(1); bsize=0; for ( n=0 ; nbsize ) bsize=cands[n].nipoint; } fitpnt=(void **)malloc(sizeof(void *)*bsize); yvals =(double *)malloc(sizeof(double)*bsize); stars=NULL; nstar=0; for ( n=0 ; nmarked ) continue; if ( wc->nipoint==0 || wc->ipoints==NULL ) continue; ipoints=wc->ipoints; for ( i=0 ; inipoint ; i++ ) { ix=wc->ipoints[i].x, iy=wc->ipoints[i].y; yvals[i]=img->data[iy][ix]; fitpnt[i]=(void *)(&ipoints[i]); } i=fit_psf(wc->nipoint,yvals,fitpnt,wc,&loc,pfp,tpd); if ( i ) continue; /* fit failed */ /*!!*/ for ( i=0 ; inipoint ; i++ ) { ix=wc->ipoints[i].x, iy=wc->ipoints[i].y; img->data[iy][ix]-=yvals[i]; } stars=(star *)realloc(stars,sizeof(star)*(nstar+1)); ws=&stars[nstar]; nstar++; memcpy(&ws->location,&loc,sizeof(starlocation)); ws->shape.model=SHAPE_PSF; ws->shape.order=0; ws->shape.gs=1.0; ws->shape.gd=ws->shape.gk=ws->shape.gl=0.0; for ( i=0 ; ishape.mom[i]=0.0; } ws->gsig=ws->gdel=ws->gkap=0.0; ws->gfwhm=ws->gellip=ws->gpa=0.0; ws->flux=ws->location.gamp; /* flux of psf is unity */ ws->marked=0; ws->cand=wc; } /* { FILE *fw; fw=fopen("psffit-temp.fits","wb"); fits_write(fw,img); fclose(fw); } */ if ( rstars != NULL ) *rstars=stars; if ( rnstar != NULL ) *rnstar=nstar; return(0); } int fit_star_psf(fitsimage *img,char **mask,candidate *cands,int ncand,star **rstars,int *rnstar,psffit *pfp,psf *tpd) { star *stars; candidate *wc; int nstar,n,b,ix,iy; linkblock *lbc,*wl; int hsize; hsize=tpd->hsize; /* fprintf(stderr,"[1]\n"); */ lbc=(linkblock *)malloc(sizeof(linkblock)*ncand); for ( n=0 ; ncx); iy=(int)floor(wc->cy); wl=&lbc[n]; wl->x1=ix-hsize,wl->x2=ix+hsize+1; wl->y1=iy-hsize,wl->y2=iy+hsize+1; wl->flag=0; } /* fprintf(stderr,"[2]\n"); */ linkblock_connect(lbc,ncand); /* fprintf(stderr,"[3]\n"); */ b=0; stars=NULL; nstar=0; for ( n=0 ; nflag ) continue; while ( wl->prev != NULL ) wl=wl->prev; for ( ; wl != NULL ; wl=wl->next ) { fprintf(stdout,"%d %d %d %d\n",wl->x1,wl->y1,wl->x2-wl->x1,0); fprintf(stdout,"%d %d %d %d\n",wl->x1,wl->y2,wl->x2-wl->x1,0); fprintf(stdout,"%d %d %d %d\n",wl->x1,wl->y1,0,wl->y2-wl->y1); fprintf(stdout,"%d %d %d %d\n",wl->x2,wl->y1,0,wl->y2-wl->y1); wl->flag=1; } b++; fprintf(stdout,"\n"); stars=(star *)realloc(stars,sizeof(star)*(nstar+1)); nstar++; } /* fprintf(stderr,"b=%d n=%d\n",b,n); */ if ( rstars != NULL ) *rstars=stars; if ( rnstar != NULL ) *rnstar=nstar; return(0); } fitsh-0.9.2/src/psf-io.c0000644000175000017500000001030711236250732013405 0ustar apalapal/*****************************************************************************/ /* psf-io.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to PSF I/O (reading/writing/dumping PSF information). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2004-2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include #include #include "tensor.h" #include "psf.h" #include "psf-io.h" /*****************************************************************************/ int psf_write(FILE *fw,psf *p) { int i,j,k,wwd,nvar; double dx,dy,igrid; wwd=p->grid*(2*p->hsize+1); nvar=(p->order+1)*(p->order+2)/2; igrid=1.0/(double)(p->grid); for ( i=0 ; icoeff[k][i][j]); fprintf(fw,"\n"); } } return(0); } /*****************************************************************************/ #define PSFHDR_PSFHSIZE 0 #define PSFHDR_PSFSGRID 1 #define PSFHDR_PSFORDER 2 #define PSFHDR_PSFOFFSX 3 #define PSFHDR_PSFOFFSY 4 #define PSFHDR_PSFSCALE 5 static char *psfheaders[] = { "PSFHSIZE", /* 0, PSFHDR_PSFHSIZE */ "PSFSGRID", /* 1, PSFHDR_PSFSGRID */ "PSFORDER", /* 2, PSFHDR_PSFORDER */ "PSFOFFSX", /* 3, PSFHDR_PSFOFFSX */ "PSFOFFSY", /* 4, PSFHDR_PSFOFFSY */ "PSFSCALE", /* 5, PSFHDR_PSFSCALE */ NULL }; int psf_write_fits(FILE *fw,psf *p) { int wwd,nvar; fits *outfits; fitsimage *out; wwd=p->grid*(2*p->hsize+1); nvar=(p->order+1)*(p->order+2)/2; outfits=fits_create(); out=&outfits->i; out->dim=3; out->naxis[0]=wwd, out->naxis[1]=wwd, out->naxis[2]=nvar; out->vdata=(void *)p->coeff; out->bit=-32; fits_set_standard(outfits,NULL);/* SIMPLE */ fits_set_image_params(outfits); /* NAXIS, NAXIS[123], BITPIX, BSCALE, BZERO */ fits_set_header_integer(outfits,psfheaders[PSFHDR_PSFHSIZE],FITS_SH_FIRST,p->hsize,NULL); fits_set_header_integer(outfits,psfheaders[PSFHDR_PSFSGRID],FITS_SH_FIRST,p->grid ,NULL); fits_set_header_integer(outfits,psfheaders[PSFHDR_PSFORDER],FITS_SH_FIRST,p->order,NULL); fits_set_header_double (outfits,psfheaders[PSFHDR_PSFOFFSX],FITS_SH_FIRST,p->ox ,NULL); fits_set_header_double (outfits,psfheaders[PSFHDR_PSFOFFSY],FITS_SH_FIRST,p->oy ,NULL); fits_set_header_double (outfits,psfheaders[PSFHDR_PSFSCALE],FITS_SH_FIRST,p->scale,NULL); fits_set_origin(outfits,"fi/src/psf.c","PSF determination"); fits_write(fw,outfits); fits_free(outfits); return(0); } int psf_parse_fits(fits *img,psf *p) { int k,wwd,nvar,order,hsize,grid,i,j; double ox,oy,scale,w; if ( img==NULL ) return(1); if ( img->i.vdata==NULL || img->i.dim != 3 ) return(1); k=0; k|=fits_get_header_as_double(img,psfheaders[0],&w,0);hsize=(int)w; k|=fits_get_header_as_double(img,psfheaders[1],&w,0);grid =(int)w; k|=fits_get_header_as_double(img,psfheaders[2],&w,0);order=(int)w; k|=fits_get_header_as_double(img,psfheaders[3],&ox,0); k|=fits_get_header_as_double(img,psfheaders[4],&oy,0); k|=fits_get_header_as_double(img,psfheaders[5],&scale,0); if ( k || hsize<=0 || grid<=0 || order<0 ) return(1); wwd=grid*(2*hsize+1); nvar=(order+1)*(order+2)/2; if ( img->i.naxis[0] != wwd || img->i.naxis[1] != wwd || img->i.naxis[2] != nvar ) return(1); p->hsize=hsize; p->grid=grid; p->order=order; p->ox=ox, p->oy=oy; p->scale=scale; p->coeff=(double ***)tensor_alloc_3d(double,wwd,wwd,nvar); for ( i=0 ; icoeff[k][i][j]=((double ***)img->i.vdata)[k][i][j]; } } return(0); } int psf_read_fits(FILE *fr,psf *p) { fits *img; img=fits_read(fr); if ( img==NULL ) return(1); if ( psf_parse_fits(img,p) ) { fits_free(img);return(1); } img->i.vdata=NULL; img->i.data=NULL; fits_free(img); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/cache.c0000644000175000017500000002710712117335320013255 0ustar apalapal/*****************************************************************************/ /* cache.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for chunked I/O caching on large files. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #ifndef HOST_WIN32 #define USE_MMAP #endif #ifdef USE_MMAP #include #endif #include "cache.h" /*****************************************************************************/ static int get_gcd(int a,int b) /* greatest common divisor */ { int c; if ( a<=0 || b<=0 ) return(-1); while ( (c=a%b)>0 ) a=b,b=c; return(b); } static int get_lcm(int a,int b) /* least common multiple */ { if ( a<=0 || b<=0 ) return(-1); return(a*b/get_gcd(a,b)); } /*****************************************************************************/ int cache_getpagesize(void) { #ifdef HOST_WIN32 return(4096); #else return(getpagesize()); #endif } int cache_blocksize(int recordsize) { int pagesize,blocksize; pagesize=cache_getpagesize(); blocksize=get_lcm(recordsize,pagesize); return(blocksize); } int cache_tcblock(int recordsize,off_t recordcount,int multip) { int pagesize,chpagesize,chnrecord,tcblock; if ( multip<=0 ) multip=1; pagesize=cache_getpagesize(); chpagesize=get_lcm(recordsize,pagesize)*multip; chnrecord=chpagesize/recordsize; tcblock=(int)((recordcount+(off_t)chnrecord-(off_t)1)/(off_t)chnrecord); return(tcblock); } int cache_init(cache *ch,int recordsize,off_t recordcount,int multip, int nchblock,int fh,int is_write) { int i; cacheblock *cb; if ( multip<=0 ) multip=1; if ( nchblock<=0 ) nchblock=1; ch->fh=fh; ch->is_write=is_write; ch->recordsize=recordsize; ch->recordcount=recordcount; ch->pagesize=cache_getpagesize(); ch->chpagesize=get_lcm(ch->recordsize,ch->pagesize)*multip; ch->chnrecord=ch->chpagesize/ch->recordsize; ch->tcblock=(int)((recordcount+(off_t)ch->chnrecord-(off_t)1)/(off_t)ch->chnrecord); ch->nn_lookup=(short *)malloc(sizeof(short)*ch->tcblock); for ( i=0 ; itcblock ; i++ ) { ch->nn_lookup[i]=-1; } ch->nchblock=nchblock; ch->chblocks=(cacheblock *)malloc(sizeof(cacheblock)*ch->nchblock); ch->nusedblock=0; ch->nmapped=0; for ( i=0 ; inchblock ; i++ ) { cb=&ch->chblocks[i]; cb->cachearray=NULL; cb->size=0; cb->nnch=-1; cb->prev=NULL; cb->next=NULL; } ch->recent=NULL; ch->oldest=NULL; return(0); } /*****************************************************************************/ static cacheblock *cache_get_block(cache *ch,int nnch,cacheblock **rchrej) { cacheblock *cb,*rc,*rj; if ( ch->recent==NULL ) { cb=&ch->chblocks[0]; ch->recent=cb; ch->oldest=cb; cb->prev=NULL; cb->next=NULL; ch->nusedblock=1; cb->nnch=nnch; ch->nn_lookup[nnch]=0; if ( rchrej != NULL ) *rchrej=NULL; return(cb); } if ( ch->recent->nnch==nnch ) { if ( rchrej != NULL ) *rchrej=NULL; return(ch->recent); } if ( ch->nn_lookup[nnch]>=0 ) { rc=&ch->chblocks[ch->nn_lookup[nnch]]; } else rc=NULL; if ( rc != NULL ) { if ( rc->prev != NULL ) rc->prev->next=rc->next; else ch->oldest=rc->next; if ( rc->next==NULL ) { fprintf(stderr,"cache_get_block():127: rc->next == NULL\n"); fprintf(stderr,"nnch=%d\n",nnch); fprintf(stderr,"ch->recordcount=%ld\n",(long)ch->recordcount); fprintf(stderr,"ch->recent->nnch=%d\n",ch->recent->nnch); fprintf(stderr,"ch->nusedblock=%d,ch->nchblock=%d\n",ch->nusedblock,ch->nchblock); exit(1); } rc->next->prev=rc->prev; ch->recent->next=rc; rc->prev=ch->recent; rc->next=NULL; ch->recent=rc; rc->nnch=nnch; if ( rchrej != NULL ) *rchrej=NULL; return(rc); } else if ( ch->nusedblocknchblock ) { rc=&ch->chblocks[ch->nusedblock]; ch->nn_lookup[nnch]=ch->nusedblock; ch->nusedblock++; ch->recent->next=rc; rc->prev=ch->recent; rc->next=NULL; ch->recent=rc; rc->nnch=nnch; if ( rchrej != NULL ) *rchrej=NULL; return(rc); } else { rj=ch->oldest; ch->nn_lookup[rj->nnch]=-1; rj->next->prev=NULL; rc=ch->oldest; ch->oldest=rj->next; ch->recent->next=rc; rc->prev=ch->recent; rc->next=NULL; ch->recent=rc; rc->nnch=nnch; ch->nn_lookup[nnch]=(ch->recent)-(ch->chblocks); if ( rchrej != NULL ) *rchrej=rj; return(rc); } } static cacheblock * cache_do_mapping(cache *ch,off_t recnum) { int nnch; cacheblock *cb,*cj; off_t offset,wf; int size; nnch=recnum/(off_t)ch->chnrecord; cb=cache_get_block(ch,nnch,&cj); /* this block should be released: */ if ( cj != NULL && cj->cachearray != NULL ) { #ifdef USE_MMAP munmap((void *)cj->cachearray,(size_t)cj->size); #else if ( ch->is_write ) { lseek(ch->fh,cj->offset,SEEK_SET); write(ch->fh,cj->cachearray,cj->size); } free(cj->cachearray); #endif ch->nmapped--; cj->cachearray=NULL; cj->size=0; } if ( cb->cachearray==NULL ) { offset=(off_t)ch->chpagesize*(off_t)nnch; wf=(off_t)ch->recordsize*(off_t)ch->recordcount-offset; if ( wf>(off_t)ch->chpagesize ) size=ch->chpagesize; else size=(int)wf; cb->size=size; cb->offset=offset; if ( ch->is_write ) { #ifdef USE_MMAP cb->cachearray=(char *)mmap(NULL,(size_t)cb->size, PROT_READ|PROT_WRITE,MAP_SHARED,ch->fh,offset); if ( (void *)cb->cachearray==(void *)(-1) ) /* mmap() failed */ { fprintf(stderr,"[rw] offset=%d %p %d nnch=%d chnrecord=%d fh=%d error='%s'\n", (int)offset,(void *)cb->cachearray,(int)cb->size,nnch,ch->chnrecord,ch->fh,strerror(errno)); return(NULL); } #else cb->cachearray=(char *)malloc((size_t)cb->size); lseek(ch->fh,(off_t)offset,SEEK_SET); read(ch->fh,cb->cachearray,(size_t)cb->size); #endif ch->nmapped++; } else { #ifdef USE_MMAP cb->cachearray=(char *)mmap(NULL,(size_t)cb->size, PROT_READ,MAP_SHARED,ch->fh,offset); if ( (void *)cb->cachearray==(void *)(-1) ) /* mmap() failed */ { fprintf(stderr,"[ro] offset=%d %p %d nnch=%d chnrecord=%d fh=%d error='%s'\n", (int)offset,(void *)cb->cachearray,(int)cb->size,nnch,ch->chnrecord,ch->fh,strerror(errno)); return(NULL); } #else cb->cachearray=(char *)malloc((size_t)cb->size); lseek(ch->fh,(off_t)offset,SEEK_SET); read(ch->fh,cb->cachearray,(size_t)cb->size); #endif ch->nmapped++; } } return(cb); } void *cache_read_record(cache *ch,off_t recnum) { int sbrc; cacheblock *cb; void *record; cb=cache_do_mapping(ch,recnum); if ( cb==NULL ) return(NULL); /* cache_do_mapping() failed */ sbrc=(int)(recnum%(off_t)ch->chnrecord); record=(void *)(cb->cachearray+sbrc*ch->recordsize); return(record); } int cache_write_record(cache *ch,off_t recnum,void *record) { int sbrc; cacheblock *cb; cb=cache_do_mapping(ch,recnum); if ( cb==NULL ) return(-1); /* cache_do_mapping() failed */ sbrc=(int)(recnum%(off_t)ch->chnrecord); memcpy((void *)(cb->cachearray+sbrc*ch->recordsize),record,ch->recordsize); return(0); } /*****************************************************************************/ static int cache_do_unmapping(cache *ch,cacheblock *cb) { if ( ch==NULL || cb==NULL ) return(-1); if ( cb->cachearray==NULL || cb->nnch<0 ) return(1); #ifdef USE_MMAP munmap((void *)cb->cachearray,(size_t)cb->size); #else if ( ch->is_write ) { lseek(ch->fh,cb->offset,SEEK_SET); write(ch->fh,cb->cachearray,cb->size); } free(cb->cachearray); #endif return(0); } static int cache_free(cache *ch) { if ( ch->chblocks != NULL ) free(ch->chblocks); if ( ch->nn_lookup != NULL ) free(ch->nn_lookup); return(0); } int cache_finalize(cache *ch) { int i; cacheblock *cb; for ( i=0 ; inchblock ; i++ ) { cb=&ch->chblocks[i]; cache_do_unmapping(ch,cb); } cache_free(ch); return(0); } /****************************************************************************** int fprint_chain_forward(FILE *fw,cache *ch) { cacheblock *cb; if ( ch->oldest==NULL ) fprintf(fw,"\n"); else { for ( cb=ch->oldest ; cb != NULL ; cb=cb->next ) { fprintf(fw,"<%d> ",cb->nnch); } fprintf(fw,"\n"); } return(0); } int fprint_chain_backward(FILE *fw,cache *ch) { cacheblock *cb; if ( ch->recent==NULL ) fprintf(fw,"\n"); else { for ( cb=ch->recent ; cb != NULL ; cb=cb->prev ) { fprintf(fw,"<%d> ",cb->nnch); } fprintf(fw,"\n"); } return(0); } int main(int argc,char *argv[]) { cache ch; char buff[256]; int nnch; cacheblock *cb; cache_init(&ch,0,256,65536,5); while ( 1 ) { fprint_chain_forward(stdout,&ch); fprint_chain_backward(stdout,&ch); nnch=-1; while ( nnch<0 ) { fgets(buff,255,stdin); sscanf(buff,"%d",&nnch); }; cb=cache_get_block(&ch,nnch,NULL); cb->nnch=nnch; }; } ******************************************************************************/ typedef struct { off_t lo; off_t hi; } stacknode; #define MAX_THRESH 4 #define PUSH(low,high) ((void)((top->lo=(low)),(top->hi=(high)),top++)) #define POP(low,high) ((void)(top--,(low=top->lo),(high=top->hi))) #define COMPARE(_p1,_p2,_v1,_v2) (_v1=cache_read_record(ch,(_p1)),\ _v2=cache_read_record(ch,(_p2)),\ compare(_v1,_v2)) #define SWAP(_p1,_p2,_v1,_v2) (memcpy(t1,_v1,recordsize),\ memcpy(t2,_v2,recordsize),\ cache_write_record(ch,(_p1),t2),\ cache_write_record(ch,(_p2),t1)) int cache_sort_block(cache *ch,off_t o,off_t n, int (*compare)(const void *,const void *)) { void *vl,*vr,*vm,*t1,*t2; stacknode stack[64],*top; off_t lo,hi,mid,left,right,end,tmp,run,trav,thresh; int recordsize; if ( n<=0 ) return(0); recordsize=ch->recordsize; t1=(void *)malloc(recordsize); t2=(void *)malloc(recordsize); lo=o; hi=o+n-1; if ( n>MAX_THRESH ) { top=&stack[1]; while ( top>stack ) { mid=lo+((hi-lo)>>1); if ( COMPARE(mid,lo,vm,vl)<0 ) SWAP(mid,lo,vm,vl); if ( COMPARE(hi,mid,vr,vm)<0 ) SWAP(hi,mid,vr,vm); else goto skip_compare; if ( COMPARE(mid,lo,vm,vl)<0 ) SWAP(mid,lo,vm,vl); skip_compare: left=lo+1; right=hi-1; do { while ( COMPARE(left,mid,vl,vm)<0 ) left++; while ( COMPARE(mid,right,vm,vr)<0 ) right--; if ( left hi-left ) { PUSH(lo,right); lo=left; } else { PUSH(left,hi); hi=right; } } } end=n-1; tmp=0; thresh=(end=run ) { off_t hi,lo; memcpy(t1,cache_read_record(ch,o+trav),recordsize); for ( hi=lo=trav ; (lo-=1)>=tmp ; hi=lo ) { memcpy(t2,cache_read_record(ch,o+lo),recordsize); cache_write_record(ch,o+hi,t2); } cache_write_record(ch,o+hi,t1); } } } free(t2); free(t1); return(0); } int cache_sort(cache *ch,int (*compare)(const void *,const void *)) { return(cache_sort_block(ch,0,ch->recordcount,compare)); } /*****************************************************************************/ fitsh-0.9.2/src/lfit-builtin.h0000644000175000017500000000505312771247471014634 0ustar apalapal/*****************************************************************************/ /* lfit-builtin.h */ /*****************************************************************************/ #ifndef __LFIT_BUILTIN_H_INCLUDED #define __LFIT_BUILTIN_H_INCLUDED 1 /*****************************************************************************/ #include /*****************************************************************************/ #define O_ADD 1 /* + */ #define O_SUB 2 /* - */ #define O_MUL 3 /* * */ #define O_DIV 4 /* / */ #define O_POW 5 /* ^ */ #define O_CHS 6 /* change sign, unary variant of '-' */ #define O_RCP 7 /* Reciprocal // these two */ #define O_PSQ 8 /* Square (power) // have no symbol */ #define O_EQU 10 #define O_NEQ 11 #define O_LS 12 #define O_GR 13 #define O_LE 14 #define O_GE 15 #define O_AND 20 #define O_OR 21 /* Basic functions */ #define F_SIN 32 #define F_COS 33 #define F_TAN 34 #define F_CTN 35 #define F_SINA 36 #define F_COSA 37 #define F_TANA 38 #define F_CTNA 39 #define F_ASIN 40 #define F_ACOS 41 #define F_ATAN 42 #define F_ACTN 43 #define F_ASINA 44 #define F_ACOSA 45 #define F_ATANA 46 #define F_ACTNA 47 #define F_ARG 48 #define F_ATAN2 49 #define F_HYPOT 50 #define F_VPI 51 #define F_EXP 52 #define F_LOG 53 #define F_EXP10 54 #define F_LOG10 55 #define F_SQR 56 #define F_ABS 57 #define F_SGN 58 #define F_THETA 59 #define F_FMOD 60 #define F_FINT 61 #define F_FDIV 62 #define F_ILINEAR 24 #define F_ILINEAR_DX 25 #define F_ISPLINE 26 #define F_ISPLINE_DX 27 #define F_ICYSPLINE 28 #define F_ICYSPLINE_DX 29 #define F_JBESSEL 64 #define F_YBESSEL 65 /*****************************************************************************/ #define LFIT_F_MAX_BUILTIN 128 /* incl. nonexported */ /*****************************************************************************/ extern short *psn_lfit_simp[]; extern psnlfit psnlfit_list_builtin_normal_operators[]; extern psnlfit psnlfit_list_builtin_relational_operators[]; extern psnlfit psnlfit_list_builtin_elementary_functions[]; extern psnlfit psnlfit_list_builtin_interpolators[]; extern psnlfit psnlfit_list_builtin_aa_functions[]; #if defined _FITSH_SOURCE || defined _ASTRO_EXTEN extern psnlfit psnlfit_list_builtin_xfuncts[]; #endif /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/fiinfo.h0000644000175000017500000000446712563135725013511 0ustar apalapal/*****************************************************************************/ /* fiinfo.h */ /*****************************************************************************/ #ifndef __FIINFO_H_INCLUDED #define __FIINFO_H_INCLUDED 1 #include #include "math/point.h" /*****************************************************************************/ typedef struct { int r,g,b; } color; typedef struct { color beg,end; } gradient; typedef struct { int is_color,is_invert,is_16bit; int minmaxmethod,scalemethod; int mmin_set,mmax_set; double manmin,manmax; double zcontrast,percentage; double contrast,brightness; gradient *palette; int ncol; int is_flip,is_mirror; } pnmparam; /* fiinfo-pnm.c */ /**********************************************************/ #define MM_MINMAX 0 /* automatic min, automatic max */ #define MM_ZSCALE 1 /* zscale */ #define MM_ZMIN 2 /* zmin */ #define MM_ZMAX 3 /* zmax */ #define MM_PERCENTAGE 4 /* percentage (see also DS9) */ #define MM_MANUAL 5 /* manual min, manual max */ #define SCALE_LINEAR 0 #define SCALE_HISTEQU 1 #define SCALE_LOG 2 #define SCALE_SQRT 3 #define SCALE_SQUARED 4 int fitsimage_dump_pnm(fitsimage *img,char **mask,FILE *fw,pnmparam *pp); int parse_palette(char *pstr,gradient **rpal,int *rncol); /* fiinfo-image.c */ /********************************************************/ int create_link_background(fitsimage *img,char **mask,fitsimage *bgi,int nx,int ny); int fits_stat_basic(fitsimage *img,char **mask,double *rmin,double *rmax,double *rmean,double *rstdd); double estimate_skysigma_naive(double *rawdata,int k,double sky,double smm,double spp); int fits_stat_raw_sky_skysigma(double *data,int ndat,double stddev,double *rsky,double *rskysigma); int fits_stat_sky(fitsimage *img,double stddev,double *rsky,double *rskysigma); double fits_stat_median(fitsimage *img); int fits_stat_background(fitsimage *img,int nbx,int nby,point **pdsky,point **pdsigma,double stddev); int fits_stat_sky_like_isis(fitsimage *img,double stddev,double *rsky,double *rskysigma); int fits_stat_sky_biquad(fitsimage *img,double stddev,double *rsky,double *rskysigma); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/star-model.c0000644000175000017500000012744512771510405014274 0ustar apalapal/*****************************************************************************/ /* star-model.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to star model fitting to a FITS image. This is the main */ /* module to create a star-list from a candidate-list. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006, Pal, A. (apal@szofi.elte.hu), part of the 'FI' package */ /*****************************************************************************/ #define __STAR_MODEL_C 1 #include #include #include #include #include #include "fitsmask.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/expint/expint.h" #include "index/multiindex.h" #include "fitsh.h" #include "common.h" #include "stars.h" #include "tensor.h" #include "statistics.h" #include "star-model.h" /*****************************************************************************/ typedef struct { double efx,efy; double exx,exy; } eeval; typedef struct { int ix0,iy0,isx,isy; double gs,gd,x0,y0; eeval *eevals; double efc,rc2s,efm; int derivative_level; /* < 0: no derivatives, */ /* 0: location /A+B/, */ /* 1: location /A+B+X+Y/ */ /* >=2: location + shape */ } gfparam; /*****************************************************************************/ /* F=B+Aexp(-1/2*S*((x-x0)^2+(y-y0)^2)) */ /* a[] = { A, B, x0, y0, S } */ /* xpnt = { ix, iy } */ void gauss_2d_nmom_exact(void *xpnt,double *a,double *yy,double *dyda,void *param) { double x,y,x1,x2,y1,y2,x0,y0,s; double efx1,efx2,efy1,efy2,efmul,efc,efm; double exx1,exx2,exy1,exy2,rc2s; x=((ipoint *)xpnt)->x,x0=a[2],x1=x-x0,x2=x1+1.0; y=((ipoint *)xpnt)->y,y0=a[3],y1=y-y0,y2=y1+1.0; s=a[4]; efc=sqrt(s/2); efx1=erf(efc*x1),efx2=erf(efc*x2); efy1=erf(efc*y1),efy2=erf(efc*y2); rc2s=0.5/s; efmul=(efx2-efx1)*(efy2-efy1)*M_PI*rc2s; *yy=a[0]*efmul+a[1]; if ( dyda != NULL ) { dyda[0]=efmul; /* \partial_A */ dyda[1]=1.0; /* \partial_B */ efm=sqrt(M_PI*rc2s); efx1*=efm,efx2*=efm; efy1*=efm,efy2*=efm; exx1=exp(-0.5*s*x1*x1),exx2=exp(-0.5*s*x2*x2); exy1=exp(-0.5*s*y1*y1),exy2=exp(-0.5*s*y2*y2); dyda[2]=a[0]*(efy2-efy1)*(exx1-exx2); /* \partial_x0 */ dyda[3]=a[0]*(efx2-efx1)*(exy1-exy2); /* \partial_y0 */ dyda[4]=a[0]*rc2s*( (efy2-efy1)*(x2*exx2-efx2-x1*exx1+efx1)+ (efx2-efx1)*(y2*exy2-efy2-y1*exy1+efy1) ); } } /* F=B+Aexp(-1/2*S*((x-x0)^2+(y-y0)^2)) */ /* a[] = { A, B, x0, y0, S } */ /* xpnt = { ix, iy } */ void gauss_2d_nmom_exact_init(void *xpnt,double *a,double *yy,double *dyda,void *param) { double x,y,x1,x2,y1,y2,x0,y0,gs; double efx1,efx2,efy1,efy2,efmul,efc,efm; double exx1,exx2,exy1,exy2,rc2s; int ix,iy; gfparam *gfp; if ( param==NULL ) { gauss_2d_nmom_exact(xpnt,a,yy,dyda,NULL); return; } gfp=(gfparam *)param; x0=a[2],y0=a[3]; gs=a[4]; if ( x0 != gfp->x0 || y0 != gfp->y0 || gs != gfp->gs ) { int j,k; efc=sqrt(0.5*gs); if ( gfp->derivative_level>0 ) { for ( k=0 ; kisx+1 ; k++ ) { x=(double)(k+gfp->ix0)-x0; gfp->eevals[k].efx=erf(efc*x); gfp->eevals[k].exx=exp(-0.5*gs*x*x); } for ( j=0 ; jisy+1 ; j++ ) { y=(double)(j+gfp->iy0)-y0; gfp->eevals[j].efy=erf(efc*y); gfp->eevals[j].exy=exp(-0.5*gs*y*y); } } else { for ( k=0 ; kisx+1 ; k++ ) { x=(double)(k+gfp->ix0)-x0; gfp->eevals[k].efx=erf(efc*x); } for ( j=0 ; jisy+1 ; j++ ) { y=(double)(j+gfp->iy0)-y0; gfp->eevals[j].efy=erf(efc*y); } } gfp->efc=efc; gfp->rc2s=0.5/gs; gfp->efm=sqrt(M_PI*gfp->rc2s); gfp->x0=x0; gfp->y0=y0; gfp->gs=gs; } else gfp->rc2s=0.0; ix=((ipoint *)xpnt)->x-gfp->ix0; iy=((ipoint *)xpnt)->y-gfp->iy0; x=((ipoint *)xpnt)->x,x1=x-x0,x2=x1+1.0; y=((ipoint *)xpnt)->y,y1=y-y0,y2=y1+1.0; efc=gfp->efc; rc2s=gfp->rc2s; efx1=gfp->eevals[ix+0].efx; efx2=gfp->eevals[ix+1].efx; efy1=gfp->eevals[iy+0].efy; efy2=gfp->eevals[iy+1].efy; efmul=(efx2-efx1)*(efy2-efy1)*M_PI*rc2s; *yy=a[0]*efmul+a[1]; if ( dyda != NULL && gfp->derivative_level>=0 ) { dyda[0]=efmul; /* \partial_A */ dyda[1]=1.0; /* \partial_B */ if ( gfp->derivative_level>0 ) { efm=gfp->efm; efx1*=efm,efx2*=efm; efy1*=efm,efy2*=efm; exx1=gfp->eevals[ix+0].exx; exx2=gfp->eevals[ix+1].exx; exy1=gfp->eevals[iy+0].exy; exy2=gfp->eevals[iy+1].exy; dyda[2]=a[0]*(efy2-efy1)*(exx1-exx2); /* \partial_x0 */ dyda[3]=a[0]*(efx2-efx1)*(exy1-exy2); /* \partial_y0 */ if ( gfp->derivative_level>=2 ) { dyda[4]=a[0]*rc2s*( (efy2-efy1)*(x2*exx2-efx2-x1*exx1+efx1)+ (efx2-efx1)*(y2*exy2-efy2-y1*exy1+efy1) ); } } } } /*****************************************************************************/ /* F=B+Aexp(-1/2*[S((x-x0)^2+(y-y0)^2)+D((x-x0)^2-(y-y0)^2)+2K(x-x0)(y-y0)]) */ /* a[] = { A, B, x0, y0, S, D, K } */ /* xpnt = { ix, iy } */ void gauss_2d_wmom_exact(void *xpnt,double *a,double *yy,double *dyda,void *p) { double x,y,x1,x2,y1,y2,x0,y0,gs,gd,gk,dlist[6]; x=((ipoint *)xpnt)->x,x0=a[2],x1=x-x0,x2=x1+1.0; y=((ipoint *)xpnt)->y,y0=a[3],y1=y-y0,y2=y1+1.0; gs=a[4],gd=a[5],gk=a[6]; expint_taylor_diff(gs,gd,gk,x1,x2,y1,y2,dlist); *yy=a[0]*dlist[0]+a[1]; if ( dyda != NULL ) { dyda[0]=dlist[0]; /* \partial_A */ dyda[1]=1.0; /* \partial_B */ dyda[2]=a[0]*dlist[1]; /* \partial_x0 */ dyda[3]=a[0]*dlist[2]; /* \partial_y0 */ dyda[4]=a[0]*dlist[3]; dyda[5]=a[0]*dlist[4]; dyda[6]=a[0]*dlist[5]; } } /* F=B+Aexp(-1/2*[S((x-x0)^2+(y-y0)^2)+D((x-x0)^2-(y-y0)^2)+2K(x-x0)(y-y0)]) */ /* a[] = { A, B, x0, y0, S, D, K } */ /* xpnt = { ix, iy } */ void gauss_2d_wmom_exact_init(void *xpnt,double *a,double *yy,double *dyda,void *param) { double x,y,x1,x2,y1,y2,x0,y0,gs,gd,gk,dlist[6],efcx,efcy; int ix,iy; gfparam *gfp; expintee ee; if ( param==NULL ) { gauss_2d_wmom_exact(xpnt,a,yy,dyda,NULL); return; } gfp=(gfparam *)param; x=((ipoint *)xpnt)->x,x0=a[2],x1=x-x0,x2=x1+1.0; y=((ipoint *)xpnt)->y,y0=a[3],y1=y-y0,y2=y1+1.0; gs=a[4],gd=a[5],gk=a[6]; if ( x0 != gfp->x0 || y0 != gfp->y0 || gs != gfp->gs || gd != gfp->gd ) { int j,k; efcx=sqrt(0.5*(gs+gd)); efcy=sqrt(0.5*(gs-gd)); for ( k=0 ; kisx+1 ; k++ ) { x=(double)(k+gfp->ix0)-x0; gfp->eevals[k].efx=erf(efcx*x); gfp->eevals[k].exx=exp(-0.5*(gs+gd)*x*x); } for ( j=0 ; jisy+1 ; j++ ) { y=(double)(j+gfp->iy0)-y0; gfp->eevals[j].efy=erf(efcy*y); gfp->eevals[j].exy=exp(-0.5*(gs-gd)*y*y); } gfp->x0=x0; gfp->y0=y0; gfp->gs=gs; gfp->gd=gd; } ix=((ipoint *)xpnt)->x-gfp->ix0; iy=((ipoint *)xpnt)->y-gfp->iy0; ee.expx1=gfp->eevals[ix+0].exx,ee.expx2=gfp->eevals[ix+1].exx; ee.expy1=gfp->eevals[iy+0].exy,ee.expy2=gfp->eevals[iy+1].exy; ee.erfx1=gfp->eevals[ix+0].efx,ee.erfx2=gfp->eevals[ix+1].efx; ee.erfy1=gfp->eevals[iy+0].efy,ee.erfy2=gfp->eevals[iy+1].efy; expint_taylor_ee_diff(gs,gd,gk,x1,x2,y1,y2,dlist,&ee); *yy=a[0]*dlist[0]+a[1]; if ( dyda != NULL && gfp->derivative_level>=0 ) { dyda[0]=dlist[0]; /* \partial_A */ dyda[1]=1.0; /* \partial_B */ if ( gfp->derivative_level>0 ) { dyda[2]=a[0]*dlist[1]; /* \partial_x0 */ dyda[3]=a[0]*dlist[2]; /* \partial_y0 */ if ( gfp->derivative_level>=2 ) { dyda[4]=a[0]*dlist[3]; dyda[5]=a[0]*dlist[4]; dyda[6]=a[0]*dlist[5]; } } } } /*****************************************************************************/ static int wdev_order; /* F=B+Aexp(-1/2*[S((x-x0)^2+(y-y0)^2)]) * */ /* ( 1 + 1/2*M_20(x-x0)^2+M_11*(x-x0)(y-y0)+1/2*M_02(y-y0)^2 + ... ) */ /* a[] = { A, B, x0, y0, S, M20, M11, M02, M30, M21, M12, M03, M40, ... } */ /* xpnt = { ix, iy } */ void gauss_2d_wdev_exact_init(void *xpnt,double *a,double *yy,double *dyda,void *param) { int order,ndev,i,j,k,jx,jy; double x,y,x1,x2,y1,y2,x0,y0,i0,s,w; double cf[MXC],cfi[MXT],cfdx[MXT],cfdy[MXT],cfds[MXT], ix[MXO+3],iy[MXO+3]; gfparam *gfp; int derivative_level; expinte e; if ( param==NULL ) { gfp=NULL; derivative_level=2; } else { gfp=(gfparam *)param; derivative_level=gfp->derivative_level; } x=((ipoint *)xpnt)->x,x0=a[2],x1=x-x0,x2=x1+1.0; y=((ipoint *)xpnt)->y,y0=a[3],y1=y-y0,y2=y1+1.0; s=a[4]; order=wdev_order; ndev=(order+1)*(order+2)/2; cf[0]=1.0; cf[1]=cf[2]=0.0; for ( i=3 ; ix-gfp->ix0; e.exp1=gfp->eevals[jx+0].exx; e.exp2=gfp->eevals[jx+1].exx; e.erf1=gfp->eevals[jx+0].efx; e.erf2=gfp->eevals[jx+1].efx; expint_list_e(s,x1,x2,order+2,ix,&e); jy=((ipoint *)xpnt)->y-gfp->iy0; e.exp1=gfp->eevals[jy+0].exy; e.exp2=gfp->eevals[jy+1].exy; e.erf1=gfp->eevals[jy+0].efy; e.erf2=gfp->eevals[jy+1].efy; expint_list_e(s,y1,y2,order+2,iy,&e); } switch ( order ) { case 2: cfi[I00]=1.0; cfi[I10]=0.0; cfi[I01]=0.0; cfi[I20]=M20*cf[I20]; cfi[I11]=M11*cf[I11]; cfi[I02]=M02*cf[I02]; i0=ix[0]*iy[0]+ cfi[I20]*ix[2]*ix[0]+ cfi[I11]*ix[1]*iy[1]+ cfi[I02]*ix[0]*iy[2]; *yy=a[1]+a[0]*i0; if ( dyda != NULL && derivative_level>=0 ) { dyda[0]=i0; /* \partial_A */ dyda[1]=1.0; /* \partial_B */ if ( derivative_level>=1 ) { cfdx[I00]=0.0; cfdx[I10]=s-cf[I20]; cfdx[I01]=-cf[I11]; cfdx[I20]=0.0; cfdx[I11]=0.0; cfdx[I02]=0.0; cfdx[I30]=M20*cf[I20]*s; cfdx[I21]=M11*cf[I11]*s; cfdx[I12]=M02*cf[I02]*s; cfdx[I03]=0.0; for ( i=0,w=0.0,k=0 ; i<=3 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) w+=cfdx[k]*ix[i-j]*iy[j]; } dyda[2]=w*a[0]; /* \partial_x0 */ cfdy[I00]=0.0; cfdy[I10]= -cf[I11]; cfdy[I01]=s-cf[I02]; cfdy[I20]=0.0; cfdy[I11]=0.0; cfdy[I02]=0.0; cfdy[I30]=0.0; cfdy[I21]=M20*cf[I20]*s; cfdy[I12]=M11*cf[I11]*s; cfdy[I03]=M02*cf[I02]*s; for ( i=0,w=0.0,k=0 ; i<=3 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) w+=cfdy[k]*ix[i-j]*iy[j]; } dyda[3]=w*a[0]; /* \partial_y0 */ } if ( derivative_level>=2 ) { cfds[I00]=0.0; cfds[I10]=0.0; cfds[I01]=0.0; cfds[I20]=1.0; cfds[I11]=0.0; cfds[I02]=1.0; cfds[I30]=0.0; cfds[I21]=0.0; cfds[I12]=0.0; cfds[I03]=0.0; cfds[I40]=M20*cf[I20]; cfds[I31]=M11*cf[I11]; cfds[I22]=M20*cf[I20]+M02*cf[I02]; cfds[I13]=M11*cf[I11]; cfds[I04]=M02*cf[I02]; for ( i=0,dyda[4]=0.0,k=0 ; i<=4 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) dyda[4]+=cfds[k]*ix[i-j]*iy[j]; } dyda[4]=-0.5*a[0]*dyda[4]; dyda[5]=a[0]*M20*ix[2]*iy[0]; dyda[6]=a[0]*M11*ix[1]*iy[1]; dyda[7]=a[0]*M02*ix[0]*iy[2]; } } break; case 3: cfi[I00]=1.0; cfi[I10]=0.0; cfi[I01]=0.0; cfi[I20]=M20*cf[I20]; cfi[I11]=M11*cf[I11]; cfi[I02]=M20*cf[I02]; cfi[I30]=M30*cf[I30]; cfi[I21]=M21*cf[I21]; cfi[I12]=M12*cf[I12]; cfi[I03]=M03*cf[I03]; i0=ix[0]*iy[0]+ cfi[I20]*ix[2]*ix[0]+ cfi[I11]*ix[1]*iy[1]+ cfi[I02]*ix[0]*iy[2]+ cfi[I30]*ix[3]*iy[0]+ cfi[I21]*ix[2]*iy[1]+ cfi[I12]*ix[1]*iy[2]+ cfi[I03]*ix[0]*iy[3]; *yy=a[1]+a[0]*i0; if ( dyda != NULL && derivative_level>=0 ) { dyda[0]=i0; /* \partial_A */ dyda[1]=1.0; /* \partial_B */ if ( derivative_level>=1 ) { cfdx[I00]=0.0; cfdx[I10]=s-M10*cf[I20]; cfdx[I01]= -M01*cf[I11]; cfdx[I20]= -M20*cf[I30]; cfdx[I11]= -M11*cf[I21]; cfdx[I02]= -M02*cf[I12]; cfdx[I30]=M20*s*cf[I20]; cfdx[I21]=M11*s*cf[I11]; cfdx[I12]=M02*s*cf[I02]; cfdx[I03]=0.0; cfdx[I40]=M30*s*cf[I30]; cfdx[I31]=M21*s*cf[I21]; cfdx[I22]=M12*s*cf[I12]; cfdx[I13]=M03*s*cf[I03]; cfdx[I04]=0.0; for ( i=0,w=0.0,k=0 ; i<=4 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) w+=cfdx[k]*ix[i-j]*iy[j]; } dyda[2]=w*a[0]; /* \partial_x0 */ cfdy[I00]=0.0; cfdy[I10]= -M10*cf[I11]; cfdy[I01]=s-M01*cf[I02]; cfdy[I20]= -M20*cf[I21]; cfdy[I11]= -M11*cf[I12]; cfdy[I02]= -M02*cf[I30]; cfdy[I30]=0.0; cfdy[I21]=M20*s*cf[I20]; cfdy[I12]=M11*s*cf[I11]; cfdy[I03]=M02*s*cf[I02]; cfdy[I40]=0.0; cfdy[I31]=M30*s*cf[I30]; cfdy[I22]=M21*s*cf[I21]; cfdy[I13]=M12*s*cf[I12]; cfdy[I04]=M03*s*cf[I03]; for ( i=0,w=0.0,k=0 ; i<=4 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) w+=cfdy[k]*ix[i-j]*iy[j]; } dyda[3]=w*a[0]; /* \partial_y0 */ } if ( derivative_level>=2 ) { cfds[I00]=0.0; cfds[I10]=0.0; cfds[I01]=0.0; cfds[I20]=1.0; cfds[I11]=0.0; cfds[I02]=1.0; cfds[I30]=0.0; cfds[I21]=0.0; cfds[I12]=0.0; cfds[I03]=0.0; cfds[I40]= M20*cf[I20]; cfds[I31]= M11*cf[I11]; cfds[I22]=M20*cf[I20]+M02*cf[I02]; cfds[I13]=M11*cf[I11]; cfds[I04]=M02*cf[I02]; cfds[I50]= M30*cf[I30]; cfds[I41]= M21*cf[I21]; cfds[I32]=M30*cf[I30]+M12*cf[I12]; cfds[I23]=M21*cf[I21]+M03*cf[I03]; cfds[I14]=M12*cf[I12]; cfds[I05]=M03*cf[I03]; for ( i=0,dyda[4]=0.0,k=0 ; i<=5 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) dyda[4]+=cfds[k]*ix[i-j]*iy[j]; } dyda[ 4]=-0.5*a[0]*dyda[4]; dyda[ 5]=a[0]*M20*ix[2]*iy[0]; dyda[ 6]=a[0]*M11*ix[1]*iy[1]; dyda[ 7]=a[0]*M02*ix[0]*iy[2]; dyda[ 8]=a[0]*M30*ix[3]*iy[0]; dyda[ 9]=a[0]*M21*ix[2]*iy[1]; dyda[10]=a[0]*M12*ix[1]*iy[2]; dyda[11]=a[0]*M03*ix[0]*iy[3]; } } break; case 4: cfi[I00]=1.0; cfi[I10]=0.0; cfi[I01]=0.0; cfi[I20]=M20*cf[I20]; cfi[I11]=M11*cf[I11]; cfi[I02]=M20*cf[I02]; cfi[I30]=M30*cf[I30]; cfi[I21]=M21*cf[I21]; cfi[I12]=M12*cf[I12]; cfi[I03]=M03*cf[I03]; cfi[I40]=M40*cf[I40]; cfi[I31]=M31*cf[I31]; cfi[I22]=M22*cf[I22]; cfi[I13]=M13*cf[I13]; cfi[I04]=M04*cf[I04]; i0=ix[0]*iy[0]+ cfi[I20]*ix[2]*ix[0]+ cfi[I11]*ix[1]*iy[1]+ cfi[I02]*ix[0]*iy[2]+ cfi[I30]*ix[3]*iy[0]+ cfi[I21]*ix[2]*iy[1]+ cfi[I12]*ix[1]*iy[2]+ cfi[I03]*ix[0]*iy[3]+ cfi[I40]*ix[4]*iy[0]+ cfi[I31]*ix[3]*iy[1]+ cfi[I22]*ix[2]*iy[2]+ cfi[I13]*ix[1]*iy[3]+ cfi[I04]*ix[0]*iy[4]; *yy=a[1]+a[0]*i0; if ( dyda != NULL && derivative_level>=0 ) { dyda[0]=i0; /* \partial_A */ dyda[1]=1.0; /* \partial_B */ if ( derivative_level>=1 ) { cfdx[I00]=0.0; cfdx[I10]= s -M10*cf[I20]; cfdx[I01]= -M01*cf[I11]; cfdx[I20]= -M20*cf[I30]; cfdx[I11]= -M11*cf[I21]; cfdx[I02]= -M02*cf[I12]; cfdx[I30]=M20*s*cf[I20] -M30*cf[I40]; cfdx[I21]=M11*s*cf[I11] -M21*cf[I31]; cfdx[I12]=M02*s*cf[I02] -M12*cf[I22]; cfdx[I03]= -M03*cf[I13]; cfdx[I40]=M30*s*cf[I30]; cfdx[I31]=M21*s*cf[I21]; cfdx[I22]=M12*s*cf[I12]; cfdx[I13]=M03*s*cf[I03]; cfdx[I04]=0.0; cfdx[I50]=M40*s*cf[I40]; cfdx[I41]=M31*s*cf[I31]; cfdx[I32]=M22*s*cf[I22]; cfdx[I23]=M13*s*cf[I13]; cfdx[I14]=M04*s*cf[I04]; cfdx[I05]=0.0; for ( i=0,w=0.0,k=0 ; i<=5 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) w+=cfdx[k]*ix[i-j]*iy[j]; } dyda[2]=w*a[0]; /* \partial_x0 */ cfdy[I00]=0.0; cfdy[I10]= -M10*cf[I11]; cfdy[I01]= s -M01*cf[I02]; cfdy[I20]= -M20*cf[I21]; cfdy[I11]= -M11*cf[I12]; cfdy[I02]= -M02*cf[I03]; cfdy[I30]= -M30*cf[I31]; cfdy[I21]=M20*s*cf[I20] -M21*cf[I22]; cfdy[I12]=M11*s*cf[I11] -M12*cf[I13]; cfdy[I03]=M02*s*cf[I02] -M03*cf[I04]; cfdy[I40]=0.0; cfdy[I31]=M30*s*cf[I30]; cfdy[I22]=M21*s*cf[I21]; cfdy[I13]=M12*s*cf[I12]; cfdy[I04]=M03*s*cf[I03]; cfdy[I50]=0.0; cfdx[I41]=M40*s*cf[I40]; cfdx[I32]=M31*s*cf[I31]; cfdx[I23]=M22*s*cf[I22]; cfdx[I14]=M13*s*cf[I13]; cfdx[I05]=M04*s*cf[I04]; for ( i=0,w=0.0,k=0 ; i<=5 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) w+=cfdy[k]*ix[i-j]*iy[j]; } dyda[3]=w*a[0]; /* \partial_y0 */ } if ( derivative_level>=2 ) { cfds[I00]=0.0; cfds[I10]=0.0; cfds[I01]=0.0; cfds[I20]=1.0; cfds[I11]=0.0; cfds[I02]=1.0; cfds[I30]=0.0; cfds[I21]=0.0; cfds[I12]=0.0; cfds[I03]=0.0; cfds[I40]= M20*cf[I20]; cfds[I31]= M11*cf[I11]; cfds[I22]=M20*cf[I20]+M02*cf[I02]; cfds[I13]=M11*cf[I11]; cfds[I04]=M02*cf[I02]; cfds[I50]= M30*cf[I30]; cfds[I41]= M21*cf[I21]; cfds[I32]=M30*cf[I30]+M12*cf[I12]; cfds[I23]=M21*cf[I21]+M03*cf[I03]; cfds[I14]=M12*cf[I12]; cfds[I05]=M03*cf[I03]; cfds[I60]= M40*cf[I40]; cfds[I51]= M31*cf[I31]; cfds[I42]=M40*cf[I40]+M22*cf[I22]; cfds[I33]=M31*cf[I31]+M13*cf[I13]; cfds[I24]=M22*cf[I22]+M04*cf[I04]; cfds[I15]=M13*cf[I13]; cfds[I06]=M04*cf[I04]; for ( i=0,dyda[4]=0.0,k=0 ; i<=6 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) dyda[4]+=cfds[k]*ix[i-j]*iy[j]; } dyda[ 4]=-0.5*a[0]*dyda[4]; dyda[ 5]=a[0]*M20*ix[2]*iy[0]; dyda[ 6]=a[0]*M11*ix[1]*iy[1]; dyda[ 7]=a[0]*M02*ix[0]*iy[2]; dyda[ 8]=a[0]*M30*ix[3]*iy[0]; dyda[ 9]=a[0]*M21*ix[2]*iy[1]; dyda[10]=a[0]*M12*ix[1]*iy[2]; dyda[11]=a[0]*M03*ix[0]*iy[3]; dyda[12]=a[0]*M40*ix[4]*iy[0]; dyda[13]=a[0]*M31*ix[3]*iy[1]; dyda[14]=a[0]*M22*ix[2]*iy[2]; dyda[15]=a[0]*M13*ix[1]*iy[3]; dyda[16]=a[0]*M04*ix[0]*iy[4]; } } break; } } /* F=B+Aexp(-1/2*[S((x-x0)^2+(y-y0)^2)]) * */ /* ( 1 + 1/2*M_20(x-x0)^2+M_11*(x-x0)(y-y0)+1/2*M_02(y-y0)^2 + ... ) */ /* a[] = { A, B, x0, y0, S, M20, M11, M02, M30, M21, M12, M03, M40, ... } */ /* xpnt = { ix, iy } */ void gauss_2d_wdev_exact(void *xpnt,double *a,double *yy,double *dyda,void *p) { gauss_2d_wdev_exact_init(xpnt,a,yy,dyda,NULL); } /*****************************************************************************/ /* level: */ /* - 0: only A and B */ /* - 1: A, B + position (X, Y) */ /* - 2: A, B, X, Y + shape (S) */ int refine_fit_model_gauss(int nipoint,double *yvals,void **fitpnt, starlocation *loc,starshape *shp,starfit *sfp,int level) { int i; int ix0,iy0,ix1,iy1,isx,isy,ix,iy,inum,nfit; double lam,afp[5],gs; void (*g2d_nmom)(void *,double *,double *,double *,void *); gfparam gfp; static eeval *eevals=NULL; static int neeval=0; g2d_nmom=gauss_2d_nmom_exact_init; if ( nipoint < 5 ) return(1); ix0=ix1=((ipoint *)fitpnt[0])->x, iy0=iy1=((ipoint *)fitpnt[0])->y; for ( i=1 ; ix, iy=((ipoint *)fitpnt[i])->y; if ( ixix1 ) ix1=ix; if ( iyiy1 ) iy1=iy; } gfp.ix0=ix0; gfp.iy0=iy0; gfp.isx=isx=ix1-ix0+1; gfp.isy=isy=iy1-iy0+1; inum=(isx>isy?isx:isy)+1; if ( eevals==NULL || inum>neeval ) { neeval=inum; eevals=(eeval *)realloc(eevals,sizeof(eeval)*neeval); } gfp.eevals=eevals; afp[0]=loc->gamp,afp[1]=loc->gbg; afp[2]=loc->gcx,afp[3]=loc->gcy; afp[4]=shp->gs; gfp.x0=afp[2],gfp.y0=afp[3]; gfp.gs=afp[4]+1.0; gfp.gd=0.0; gfp.derivative_level=level; if ( level <= 0 ) { lin_fit(fitpnt,yvals,afp,NULL,g2d_nmom,2,nipoint,&gfp,NULL); } else { if ( level==1 ) nfit=4; else nfit=5; lam=0.001; for ( i=0 ; iiter_symmetric && isfinite(afp[0]) ; i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,g2d_nmom,nfit,nipoint,&gfp,lam,10.0); } for ( i=0 ; i<5 ; i++ ) { if ( ! isfinite(afp[i]) ) return(1); } loc->gamp=afp[0],loc->gbg=afp[1]; loc->gcx=afp[2],loc->gcy=afp[3]; gs=afp[4]; if ( gs<=0.0 ) return(1); shp->model=SHAPE_GAUSS; shp->order=0; shp->gs=gs; shp->gd=shp->gk=shp->gl=0.0; return(0); } int fit_model_gauss(int nipoint,double *yvals,void **fitpnt,candidate *wc, starlocation *loc,starshape *shp,starfit *sfp) { int ret; loc->gamp=wc->amp, loc->gbg =wc->bg; loc->gcx =wc->cx; loc->gcy =wc->cy; shp->gs=(wc->sxx+wc->syy)/2.0; ret=refine_fit_model_gauss(nipoint,yvals,fitpnt,loc,shp,sfp,2); return(ret); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* level: */ /* - 0: only A and B */ /* - 1: A, B + position (X, Y) */ /* - 2: A, B, X, Y + shape (S, D, K) */ int refine_fit_model_elliptic_gauss(int nipoint,double *yvals,void **fitpnt, starlocation *loc,starshape *shp,starfit *sfp,int level) { int i,ix,iy; int ix0,iy0,ix1,iy1,isx,isy,inum,nfit; double lam,afp[7],gs,gd,gk; void (*g2d_wmom)(void *,double *,double *,double *,void *); gfparam gfp; static eeval *eevals=NULL; static int neeval=0; g2d_wmom=gauss_2d_wmom_exact_init; if ( level<=0 ) nfit=2; else if ( level==1 ) nfit=4; else nfit=7; if ( nipoint < nfit ) return(1); ix0=ix1=((ipoint *)fitpnt[0])->x, iy0=iy1=((ipoint *)fitpnt[0])->y; for ( i=1 ; ix, iy=((ipoint *)fitpnt[i])->y; if ( ixix1 ) ix1=ix; if ( iyiy1 ) iy1=iy; } gfp.ix0=ix0; gfp.iy0=iy0; gfp.isx=isx=ix1-ix0+1; gfp.isy=isy=iy1-iy0+1; inum=(isx>isy?isx:isy)+1; if ( eevals==NULL || inum>neeval ) { neeval=inum; eevals=(eeval *)realloc(eevals,sizeof(eeval)*neeval); } gfp.eevals=eevals; afp[0]=loc->gamp,afp[1]=loc->gbg; afp[2]=loc->gcx, afp[3]=loc->gcy; afp[4]=shp->gs; afp[5]=shp->gd; afp[6]=shp->gk; gfp.x0=afp[2],gfp.y0=afp[3]; gfp.gs=afp[4]+1.0; gfp.gd=0.0; gfp.derivative_level=level; if ( level<=0 ) { lin_fit(fitpnt,yvals,afp,NULL,g2d_wmom,2,nipoint,&gfp,NULL); } else { lam=0.001; /* for ( i=0 ; iiter_symmetric && isfinite(afp[0]); i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,g2d_nmom,(nfit<5?nfit:5),nipoint,&gfp,lam,10.0); */ for ( i=0 ; iiter_general && isfinite(afp[0]) ; i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,g2d_wmom,nfit,nipoint,&gfp,lam,10.0); } for ( i=0 ; i<7 ; i++ ) { if ( ! isfinite(afp[i]) ) return(1); } loc->gamp=afp[0],loc->gbg=afp[1]; loc->gcx=afp[2],loc->gcy=afp[3]; gs=afp[4],gd=afp[5],gk=afp[6]; if ( gs<=0.0 || gs*gs-gd*gd-gk*gk<=0.0 ) return(1); shp->model=SHAPE_ELLIPTIC; shp->order=0; shp->gs=gs; shp->gd=gd, shp->gk=gk; shp->gl=0.0; return(0); } int fit_model_elliptic_gauss(int nipoint,double *yvals,void **fitpnt,candidate *wc, starlocation *loc,starshape *shp,starfit *sfp) { int ret; loc->gamp=wc->amp, loc->gbg =wc->bg; loc->gcx =wc->cx; loc->gcy =wc->cy; shp->gs=(wc->sxx+wc->syy)/2.0; shp->gd=0.0; shp->gk=0.0; ret=refine_fit_model_elliptic_gauss(nipoint,yvals,fitpnt,loc,shp,sfp,2); return(ret); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int refine_fit_model_deviated(int nipoint,double *yvals,void **fitpnt, starlocation *loc,starshape *shp,starfit *sfp,int level) { return(0); } int fit_model_deviated(int nipoint,double *yvals,void **fitpnt,candidate *wc, starlocation *loc,starshape *shp,starfit *sfp,int order) { int i; double lam,afp[MAX_DEVIATION_COEFF+5],gs,wgs,wgd,wgk,ndev,ndev0,ntot,*dcf; void (*g2d_nmom)(void *,double *,double *,double *,void *); void (*g2d_wdev)(void *,double *,double *,double *,void *); g2d_nmom=gauss_2d_nmom_exact; g2d_wdev=gauss_2d_wdev_exact; ndev0=(order+1)*(order+2)/2; ndev=ndev0-3; ntot=ndev+5; if ( nipoint < ntot ) return(1); lam=0.001; afp[0]=wc->amp,afp[1]=wc->bg; afp[2]=wc->cx ,afp[3]=wc->cy; afp[4]=(wc->sxx+wc->syy)/2.0; for ( i=0 ; iiter_symmetric ; i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,g2d_nmom,5,nipoint,NULL,lam,10.0); for ( i=0 ; i<5 ; i++ ) { if ( ! isfinite(afp[i]) ) return(1); } dcf=&afp[5]; for ( i=0 ; iiter_general ; i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,g2d_wdev,ntot,nipoint,NULL,lam,10.0); for ( i=0 ; igamp=afp[0],loc->gbg=afp[1]; loc->gcx =afp[2],loc->gcy=afp[3]; gs=afp[4]; wgs=afp[4]-(afp[5]+afp[7])*0.5; wgd=-(afp[5]-afp[7])*0.5; wgk=-(afp[6]); if ( gs <= 0.0 || wgs<=0.0 || wgs*wgs-wgd*wgd-wgk*wgk<=0.0 ) return(1); shp->model=SHAPE_DEVIATED; shp->order=order; shp->gs=gs; shp->gd=wgd, shp->gk=wgk; shp->gl=0.0; for ( i=0 ; imom[i]=dcf[i]; } for ( ; imom[i]=0.0; } return(0); } /*****************************************************************************/ int fit_model_combined(int nipoint,double *yvals,void **fitpnt,candidate *wc, starlocation *loc,starshape *mshps,int n, starmodelfit *smfs,starfit *sfp) { int i,j,nshape,nfv,is_failed; double lam,*afp,bg,gs,gd,gk,gg; modelparam *mps; void (*funct)(void *,double *,double *,double *,void *); mps=(modelparam *)malloc(sizeof(modelparam)*(n+1)); nfv=3; for ( i=0 ; iamp,afp[1]=wc->bg; afp[2]=wc->cx,afp[3]=wc->cy; afp[4]=(wc->sxx+wc->syy)/2.0; for ( i=0 ; iiter_symmetric ; i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,funct,5,nipoint,NULL,lam,10.0); bg=afp[1]; afp[1]=afp[2]; afp[2]=afp[3]; afp[3]=afp[0]; afp[0]=bg; nfv=3; for ( i=0 ; i0 ) { afp[0+nfv]=0.1*afp[3]; afp[1+nfv]=0.5*afp[4]; } nfv+=1+nshape; } /* fprintf(stderr,"nfv=%d\n",nfv); for ( i=0 ; iiter_general ; i++ ) lam=nlm_fit_base(fitpnt,yvals,afp,NULL,model_combine,nfv,nipoint,mps,lam,10.0); } /* fprintf(stderr,"nfv=%d\n",nfv); for ( i=0 ; igbg=afp[0]; loc->gcx=afp[1]; loc->gcy=afp[2]; loc->gamp=0.0; nfv=3; is_failed=0; for ( i=0 ; igamp += mshps[i].factor; nfv+=1+nshape; } if ( ! is_failed ) { for ( i=0 ; igamp; } } free(afp); free(mps); return(is_failed); } /*****************************************************************************/ int fit_star_single_model(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,starfit *sfp,int shapemodel,int modelorder) { int i,n,bsize; ipoint *ipoints; void **fitpnt;double *yvals; star *stars,*ws; candidate *wc; int nstar; starshape shp; starlocation loc; if ( rstars != NULL ) *rstars=NULL; if ( rnstar != NULL ) *rnstar=0; if ( ncand == 0 ) return(0); else if ( ncand < 0 ) return(1); bsize=0; for ( n=0 ; nbsize ) bsize=cands[n].nipoint; } fitpnt=(void **)malloc(sizeof(void *)*bsize); yvals =(double *)malloc(sizeof(double)*bsize); stars=NULL; nstar=0; for ( n=0 ; nmarked ) continue; if ( wc->nipoint==0 || wc->ipoints==NULL ) continue; ipoints=wc->ipoints; for ( i=0 ; inipoint ; i++ ) { int ix,iy; ix=wc->ipoints[i].x, iy=wc->ipoints[i].y; yvals[i]=img->data[iy][ix]; fitpnt[i]=(void *)(&ipoints[i]); } switch ( shapemodel ) { case SHAPE_GAUSS: i=fit_model_gauss(wc->nipoint,yvals,fitpnt,wc,&loc,&shp,sfp); break; case SHAPE_ELLIPTIC: i=fit_model_elliptic_gauss(wc->nipoint,yvals,fitpnt,wc,&loc,&shp,sfp); break; case SHAPE_DEVIATED: i=fit_model_deviated(wc->nipoint,yvals,fitpnt,wc,&loc,&shp,sfp,modelorder); break; default: i=-1; break; } if ( i ) continue; stars=(star *)realloc(stars,sizeof(star)*(nstar+1)); ws=&stars[nstar]; nstar++; memcpy(&ws->location,&loc,sizeof(starlocation)); memcpy(&ws->shape,&shp,sizeof(starshape)); #ifdef STAR_MULTIMODEL ws->mshapes=NULL; ws->nmshape=1; #endif star_set_common_shape_params(shp.gs,shp.gd,shp.gk,ws); ws->flux=loc.gamp*star_get_unity_flux(&shp); ws->marked=0; ws->cand=wc; } free(yvals); free(fitpnt); if ( rstars != NULL ) *rstars=stars; if ( rnstar != NULL ) *rnstar=nstar; return(0); } /*****************************************************************************/ #ifdef STAR_MULTIMODEL int fit_star_multi_models(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,starfit *sfp,starmodelfit *smfs,int nsmf) { int i,sx,sy,n,bsize,nmshp; ipoint *ipoints; void **fitpnt;double *yvals; double gs,gd,gk,gg,gm; star *stars,*ws; candidate *wc; int nstar; starshape *mshps,*sw; starlocation loc; if ( rstars != NULL ) *rstars=NULL; if ( rnstar != NULL ) *rnstar=0; if ( ncand == 0 ) return(0); else if ( ncand < 0 ) return(1); if ( nsmf<=0 ) return(1); sx=img->sx,sy=img->sy; bsize=0; for ( n=0 ; nbsize ) bsize=cands[n].nipoint; } fitpnt=(void **)malloc(sizeof(void *)*bsize); yvals =(double *)malloc(sizeof(double)*bsize); stars=NULL; nstar=0; for ( n=0 ; nmarked ) continue; if ( wc->nipoint==0 || wc->ipoints==NULL ) continue; ipoints=wc->ipoints; for ( i=0 ; inipoint ; i++ ) { int ix,iy; ix=wc->ipoints[i].x, iy=wc->ipoints[i].y; yvals[i]=img->data[iy][ix]; fitpnt[i]=(void *)(&ipoints[i]); } nmshp=nsmf; mshps=(starshape *)malloc(sizeof(starshape)*nmshp); i=fit_model_combined(wc->nipoint,yvals,fitpnt,wc,&loc,mshps,nmshp,smfs,sfp); if ( i ) { free(mshps);continue; } /* fit failed */ gs=mshps[0].gs, /* mshps[0] is assumed to be the dominant model */ gd=mshps[0].gd, gk=mshps[0].gk; gg=gs*gs-gd*gd-gk*gk; if ( gg<=0.0 ) { free(mshps);continue; } /* fit failed */ gm=sqrt(gg); stars=(star *)realloc(stars,sizeof(star)*(nstar+1)); ws=&stars[nstar]; nstar++; memcpy(&ws->location,&loc,sizeof(starlocation)); if ( nmshp==1 ) /* only one model... */ { memcpy(&ws->shape,mshps,sizeof(starshape)); ws->mshapes=NULL; ws->nmshape=1; free(mshps); } else /* ...combined model */ { ws->mshapes=mshps; ws->nmshape=nmshp; } star_set_common_shape_params(gs,gd,gk,ws); ws->flux=0; for ( i=0 ; imshapes != NULL ) sw=&ws->mshapes[i]; else sw=&ws->shape; ws->flux += loc.gamp*sw->factor*star_get_unity_flux(sw); } ws->marked=0; ws->cand=wc; } free(yvals); free(fitpnt); if ( rstars != NULL ) *rstars=stars; if ( rnstar != NULL ) *rnstar=nstar; return(0); } /* int fit_star_model(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,starfit *sfp,int shapemodel,int modelorder) { starmodelfit smf; smf.model=shapemodel; smf.order=modelorder; fit_star_multi_models(img,mask,cands,ncand,rstars,rnstar,sfp,&smf,1); return(0); } */ #endif /*****************************************************************************/ int drawback_model_gauss(ipoint *ipoints,int nipoint,double *yvals,starlocation *loc,starshape *shp,double mul) { int i; int ix0,iy0,ix1,iy1,isx,isy,ix,iy,inum; double afp[5],y; void (*g2d_nmom)(void *,double *,double *,double *,void *); gfparam gfp; static eeval *eevals=NULL; static int neeval=0; g2d_nmom=gauss_2d_nmom_exact_init; ix0=ix1=ipoints[0].x, iy0=iy1=ipoints[0].y; for ( i=1 ; iix1 ) ix1=ix; if ( iyiy1 ) iy1=iy; } gfp.ix0=ix0; gfp.iy0=iy0; gfp.isx=isx=ix1-ix0+1; gfp.isy=isy=iy1-iy0+1; inum=(isx>isy?isx:isy)+1; if ( eevals==NULL || inum>neeval ) { neeval=inum; eevals=(eeval *)realloc(eevals,sizeof(eeval)*neeval); } gfp.eevals=eevals; afp[0]=loc->gamp,afp[1]=0.0; afp[2]=loc->gcx,afp[3]=loc->gcy; afp[4]=shp->gs; gfp.x0=afp[2],gfp.y0=afp[3]; gfp.gs=afp[4]+1.0; gfp.gd=0.0; gfp.derivative_level=-1; /* no derivatives required for drawback */ for ( i=0 ; iix1 ) ix1=ix; if ( iyiy1 ) iy1=iy; } gfp.ix0=ix0; gfp.iy0=iy0; gfp.isx=isx=ix1-ix0+1; gfp.isy=isy=iy1-iy0+1; inum=(isx>isy?isx:isy)+1; if ( eevals==NULL || inum>neeval ) { neeval=inum; eevals=(eeval *)realloc(eevals,sizeof(eeval)*neeval); } gfp.eevals=eevals; afp[0]=loc->gamp,afp[1]=0.0; afp[2]=loc->gcx,afp[3]=loc->gcy; afp[4]=shp->gs; afp[5]=shp->gd; afp[6]=shp->gk; gfp.x0=afp[2],gfp.y0=afp[3]; gfp.gs=afp[4]+1.0; gfp.gd=0.0; gfp.derivative_level=-1; /* no derivatives required for drawback */ for ( i=0 ; imodel ) { case SHAPE_GAUSS: drawback_model_gauss(ipoints,nipoint,yvals,loc,shp,mul); break; case SHAPE_ELLIPTIC: drawback_model_elliptic_gauss(ipoints,nipoint,yvals,loc,shp,mul); break; case SHAPE_DEVIATED: drawback_model_deviated(ipoints,nipoint,yvals,loc,shp,mul); break; } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int collective_fit_star_single_model(fitsimage *img,char **mask, star *stars,int nstar,ipointlist *ipl,starfit *sfp,int is_putback,int level) { int i,n,bsize,nipoint; ipoint *ipoints; void **fitpnt; double *yvals; star *ws; starshape shp; starlocation loc; bsize=0; for ( n=0 ; nbsize ) bsize=ipl[n].nipoint; } fitpnt=(void **)malloc(sizeof(void *)*bsize); yvals =(double *)malloc(sizeof(double)*bsize); for ( n=0 ; nmarked ) continue; for ( i=0 ; idata[iy][ix]; fitpnt[i]=(void *)(&ipoints[i]); } if ( is_putback ) { drawback_model(ipoints,nipoint,yvals,&ws->location,&ws->shape,+1); } memcpy(&loc,&ws->location,sizeof(starlocation)); memcpy(&shp,&ws->shape,sizeof(starshape)); switch ( shp.model ) { case SHAPE_GAUSS: i=refine_fit_model_gauss(nipoint,yvals,fitpnt,&loc,&shp,sfp,level); break; case SHAPE_ELLIPTIC: i=refine_fit_model_elliptic_gauss(nipoint,yvals,fitpnt,&loc,&shp,sfp,level); break; case SHAPE_DEVIATED: i=refine_fit_model_deviated(nipoint,yvals,fitpnt,&loc,&shp,sfp,level); break; default: i=-1; break; } /* if the fit was successful, overwrite the old star parameters with the refined ones,... */ if ( ! i && loc.gamp>0 ) { memcpy(&ws->location,&loc,sizeof(starlocation)); memcpy(&ws->shape,&shp,sizeof(starshape)); } /* ... otherwise, skip the star... */ else ws->marked=1; } free(yvals); free(fitpnt); return(0); } int collective_fit_star_single_model_iterative(fitsimage *img,char **mask, star *stars,int nstar,ipointlist *ipl,starfit *sfp,int level,int niter) { int i,j,ix,iy,sx,sy,n,k,bsize,nipoint; ipoint *ipoints; double *yvals; fitsimage fitimg_data,*fitimg; star *ws; sx=img->sx,sy=img->sy; bsize=0; for ( n=0 ; nbsize ) bsize=ipl[n].nipoint; } yvals =(double *)malloc(sizeof(double)*bsize); collective_fit_star_single_model(img,mask,stars,nstar,ipl,sfp,0,0); if ( niter>0 ) { fitimg=&fitimg_data; fits_image_duplicate(fitimg,img,1); for ( k=0 ; kmarked ) continue; for ( i=0 ; idata[iy][ix]; } drawback_model(ipoints,nipoint,yvals,&ws->location,&ws->shape,-1); for ( i=0 ; idata[iy][ix]=yvals[i]; } } collective_fit_star_single_model(fitimg,mask,stars,nstar,ipl,sfp,1,level); for ( i=0 ; idata[i][j]=img->data[i][j]; } } } fits_image_free(fitimg); } for ( n=0 ; nshape.gs,ws->shape.gd,ws->shape.gk,ws); ws->flux=ws->location.gamp*star_get_unity_flux(&ws->shape); } free(yvals); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int index_compare_star_sort_x(int p1,int p2,void *param) { star *stars=(star *)param; if ( stars[p1].location.gcx < stars[p2].location.gcx ) return(-1); else if ( stars[p1].location.gcx > stars[p2].location.gcx ) return(1); else return(0); } static int index_compare_star_sort_y(int p1,int p2,void *param) { star *stars=(star *)param; if ( stars[p1].location.gcy < stars[p2].location.gcy ) return(-1); else if ( stars[p1].location.gcy > stars[p2].location.gcy ) return(1); else return(0); } static int index_compare_star_value_x(int p,double x,void *param) { star *stars=(star *)param; if ( stars[p].location.gcx < x ) return(-1); else if ( stars[p].location.gcx > x ) return(1); else return(0); } static int index_compare_star_value_y(int p,double y,void *param) { star *stars=(star *)param; if ( stars[p].location.gcy < y ) return(-1); else if ( stars[p].location.gcy > y ) return(1); else return(0); } typedef struct { int ndat; double *bgs; double *amps; } sfdata; int collective_fit_star_single_model_blocked(fitsimage *img,char **mask, star *stars,int nstar,ipointlist *ipl,double bhsize) { int i,j,k,n,asize,nipoint,ix0,ix1,iy0,iy1,isx,isy,ix,iy; int p,q,r,t,c; ipoint *ipoints; double *yvaldata,**ypl,x0,x1,y0,y1,**amatrix,*bvector,*fvars; star *ws; multiindex mi; int *ixs,***idmx,*ipx; int nix,mnx,nvar; sfdata *sfs; multiindex_create(stars,nstar, index_compare_star_sort_x, index_compare_star_sort_y, &mi); sfs=(sfdata *)malloc(sizeof(sfdata)*nstar); for ( n=0 ; nlocation.gamp=1.0; drawback_model(ipoints,nipoint,ypl[n],&ws->location,&ws->shape,+1.0); } mnx=64; ixs=(int *)malloc(sizeof(int)*mnx); amatrix=matrix_alloc(mnx+1); bvector=vector_alloc(mnx+1); fvars =vector_alloc(mnx+1); for ( n=0 ; nlocation.gcx-bhsize,x1=ws->location.gcx+bhsize; y0=ws->location.gcy-bhsize,y1=ws->location.gcy+bhsize; nix=multiindex_range_query(&mi, index_compare_star_value_x, index_compare_star_value_y, x0,x1,y0,y1,ixs,mnx); while ( nix>=mnx ) { vector_free(fvars); vector_free(bvector); matrix_free(amatrix); mnx=2*mnx; ixs=(int *)realloc(ixs,sizeof(int)*mnx); nix=multiindex_range_query(&mi, index_compare_star_value_x, index_compare_star_value_y, x0,x1,y0,y1,ixs,mnx); amatrix=matrix_alloc(mnx+1); bvector=vector_alloc(mnx+1); fvars =vector_alloc(mnx+1); }; nvar=nix+1; for ( i=0 ; i ix1 ) ix1=ipoints[i].x; if ( ipoints[i].y < iy0 ) iy0=ipoints[i].y; if ( ipoints[i].y > iy1 ) iy1=ipoints[i].y; } } ix1++,iy1++; isx=ix1-ix0; isy=iy1-iy0; idmx=tensor_alloc_3d(int,2*nix+1,isx,isy); for ( i=0 ; idata[iy0+i][ix0+j]; } t++; } } /*fprintf(stderr,"nvar=%d t=%d isx=%d isy=%d\n",nvar,t,isx,isy);*/ solve_gauss(amatrix,bvector,nvar); for ( k=0 ; klocation.gbg=bvector[0]; for ( k=0 ; klocation.gamp=bvector[k+1]; } */ tensor_free(idmx); } vector_free(fvars); vector_free(bvector); matrix_free(amatrix); free(ixs); free(ypl); free(yvaldata); multiindex_free(&mi); for ( n=0 ; nlocation.gbg =median(sfs[n].bgs ,r); ws->location.gamp=median(sfs[n].amps,r); free(sfs[n].amps); free(sfs[n].bgs); star_set_common_shape_params(ws->shape.gs,ws->shape.gd,ws->shape.gk,ws); ws->flux=ws->location.gamp*star_get_unity_flux(&ws->shape); } free(sfs); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/lfit.c0000644000175000017500000056437612771511206013173 0ustar apalapal/*****************************************************************************/ /* lfit.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Symbolic fitting & arithmetic evaluating utility. Supported (fit) methods:*/ /* - NONE: simple evaluation of a set of functions */ /* - CLLS: classical linear least squares method */ /* - NLLM: nonlinear Levenberg-Marquardt least squares methods */ /* - MCMC: Markov chain Monte-Carlo method */ /* - MCHI: mapping of values of chi2 on a grid */ /* - EMCE: error estimation based on synthetic Monte-Carlo re-fitting */ /* - DHSX: downhill simplex minimalization */ /* - XMMC: extended Markov chain Monte-Carlo method */ /* - LMND: Levenberg-Marquardt with numerical approximation for derivatives */ /* - FIMA: Fisher Information Matrix Analysis (not really a fit method) */ /* The set of built-in functions are definded in the `lfit-builtin.[ch]` */ /* modules. Additional functions can easily be registered by using */ /* the function lfit_register_function() (see _FITSH_SOURCE part for example)*/ /* Further extensions are also available runtime, using dynamically loaded */ /* external shared libraries (see -d|--dynamic option or `linear.c` for ex.) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 1996, 2002, 2004-2005, 2006, 2007-2008, 2009; */ /* Pal, Andras (apal@szofi.net) */ /*****************************************************************************/ #define LFIT_VERSION "7.9" #define LFIT_LASTCHANGE "2009.05.25" /*****************************************************************************/ #include #include #include #include #include #include #include #include #ifndef HOST_WIN32 #include #endif #include #include #include "longhelp.h" #include "fitsh.h" #include #include "lfit-info.h" #include "lfit-builtin.h" #ifndef HOST_WIN32 #define LFIT_ENABLE_DYNAMIC_EXTENSIONS 1 #endif #ifdef LFIT_ENABLE_DYNAMIC_EXTENSIONS #include #endif #if defined _CHDET_SOURCE #include "psn.h" #include "str.h" #include "iof.h" #include "tokenize.h" #include "scanarg.h" #include "lmfit.h" #include "pbfft.h" #include "downhill.h" #include "random.h" #elif defined _FITSH_SOURCE #include "str.h" #include #include #include "io/iof.h" #include "io/tokenize.h" #include "io/scanarg.h" #include "math/fit/lmfit.h" #include "math/dft/pbfft.h" #include "math/fit/downhill.h" #else #include #include "str.h" #include "iof.h" #include "tokenize.h" #include "scanarg.h" #include "lmfit.h" #include "pbfft.h" #include "downhill.h" #include "random.h" #endif /*****************************************************************************/ #define LFIT_DEFAULT_FORMAT "%12g" #define LFIT_DEFAULT_CORR_FORMAT "%6.3f" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define RESIDUAL_BIASED 0 #define RESIDUAL_UNBIASED 1 #define RESIDUAL_CHI2 2 #define RESIDUAL_BIASED_CHI2 2 #define RESIDUAL_UNBIASED_CHI2 3 /*****************************************************************************/ #ifndef M_PI #define M_PI 3.1415926535897932384626433832795028841968 #endif /*****************************************************************************/ typedef struct { char *name; psn *pmacro; int major; int argnum; } psnmacro; typedef struct { lfitfunction *lff; int fmajor; int nmajor; double *diff; } lffreg; typedef struct { psnsym * pl_sym; int nsym; psnprop * pl_prop; int nprop; psnfunct * pl_funct; int nfunct; psndiff * pl_diff; int ndiff; psnsymeval * pl_symeval; int nsymeval; psnmacro * pl_macro; char **symbols; int nsymbol; short **pl_simp; lffreg *lffregs; int nlffreg; } lfitpsnglobal; lfitpsnglobal lpg = { NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, 0, psn_lfit_simp, NULL, 0 }; /*****************************************************************************/ int error_vpush(char **rstr,char *prefix,char *fmt,va_list ip) { int n,l,p,size; char *str,*nstr; /* va_list ap; */ if ( rstr==NULL ) return(1); str=NULL; l=0; size=128; str=realloc(str,l+size); if ( str==NULL ) return(-1); while ( 1 ) { /* va_copy(ap,ip); */ n=vsnprintf((str)+l,size,fmt,ip); /* va_end(ap); */ if ( n>-1 && n-1 ) size=n+1; else size=size*2; if ( (nstr=realloc(str,l+size))==NULL ) { free(str); return(-1); } else str=nstr; }; if ( *rstr==NULL ) *rstr=str; else { l=strlen(*rstr); if ( prefix==NULL ) p=0; else p=strlen(prefix); *rstr=realloc((*rstr),l+p+n+1); memmove((*rstr)+n+p,(*rstr),l+1); memcpy((*rstr),str,n); if ( p>0 ) memcpy((*rstr)+n,prefix,p); free(str); } return(0); } int error_push(char **rstr,char *prefix,char *fmt,...) { va_list ip; int r; va_start(ip,fmt); r=error_vpush(rstr,prefix,fmt,ip); va_end(ip); return(r); } int error_free(char **rstr) { if ( rstr==NULL ) return(-1); else if ( *rstr==NULL ) return(1); else { free(*rstr); return(0); } } int lfit_error_push(char **rstr,char *fmt,...) { va_list ip; int r; va_start(ip,fmt); r=error_vpush(rstr,": ",fmt,ip); va_end(ip); return(r); } int lfit_error_fprint_error(char **rstr) { lfit_error_push(rstr,"error"); lfit_error_push(rstr,"lfit"); fprintf(stderr,"%s.\n",*rstr); return(0); } int lfit_error_fprint_warning(char **rstr) { lfit_error_push(rstr,"error"); lfit_error_push(rstr,"lfit"); fprintf(stderr,"%s.\n",*rstr); return(0); } /*****************************************************************************/ char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ char *errmsgs[]= { "", /* dummy */ /* 1 */ "invalid command line argument (see --help for help)", /* 2 */ "unable to open input file", /* 3 */ "unable to create output file", /* 4 */ "definition of fit variables missing, use -v 'vars' to define", /* 5 */ "column definitions missing, use -c 'cols' to define", /* 6 */ "fit function is missing, use -f 'func' to define one", /* 7 */ "invalid function (symbolic error)", /* 8 */ "invalid function (parse error)", /* 9 */ "fatal - inconsistency in the psn library!", /*10 */ "too few lines for fitting", /*11 */ "singular matrix", /*12 */ "invalid dependent expression (symbolic error)", /*13 */ "invalid dependent expression (parse error)", /*14 */ "fit function is non-linear in one of the fitting parameters", /*15 */ "dependent value missing or ambigous, use -y 'expr' or -f '...=expr' to define", /*16 */ "non-differentable operator in the fitting function", /*17 */ "unable to create output list file for fitted lines", /*18 */ "unable to create output list file for rejected lines", /*19 */ "invalid, singular or non-linear constraint", /*20 */ "constraints can be used only with linear fits", /*21 */ "too many constraints", /*22 */ "invalid column specification (note that each column can only be defined once)", /*23 */ "none of the fit or dependent expressions contain variables to be fitted", /*24 */ "both fit and dependent expression contain variables to be fitted", /*25 */ "unable to create output list file", /*26 */ "unable to create variable list file", /*27 */ "unable to create MCMC output file", /*28 */ "invalid combination of input fit data", /*29 */ "both error and weight have been defined, use only one of them", /*30 */ "input file name is missing, use -i 'filename' to define", /*31 */ "some of the data blocks are used for fitting, some of them are not - be consequent", /*32 */ "invalid chi-weight format or value", /*33 */ "invalid variable format string", /*34 */ "invalid string for variable differences", NULL }; /* int effective_strlen(char *s) { int r; for ( r=0 ; *s != 0 ; s++ ) { if ( *s == '\t' ) r=(r+8)&(~7); else r++; } return(r); } */ int fprint_lfit_function_description(FILE *fw,int width,int w,int pad,char *desc) { int i; for ( i=w ; i0 ) l++; if ( l>width-p ) { fprintf(fw,"\n"); for ( i=0 ; i0 ) l--; w=0; p=pad; } if ( w>0 ) fprintf(fw," %s",cmd[n]); else fprintf(fw,"%s",cmd[n]); p+=l; w++; }; fprintf(fw,"\n"); if ( cmd != NULL ) free(cmd); free(dd); } return(0); } int fprint_lfit_function_info(FILE *fw,int width,psnlfit *pl) { int w; if ( pl->info==NULL ) return(1); else if ( pl->type==T_OP ) { if ( pl->minor==TO_INFIX ) { fprintf(fw,"(.)%s(.)",pl->name); w=3+strlen(pl->name)+3; } else if ( pl->minor==TO_PREFIX ) { fprintf(fw,"%s(.)",pl->name); w=strlen(pl->name)+3; } else if ( pl->minor==TO_SUFFIX ) { fprintf(fw,"(.)%s",pl->name); w=3+strlen(pl->name); } else return(1); if ( pl->info != NULL && pl->info->description != NULL ) fprint_lfit_function_description(fw,width,w,16,pl->info->description); else fprintf(fw,"\n"); return(0); } else if ( pl->type==T_FN ) { int i; fprintf(fw,"%s(",pl->name); w=strlen(pl->name)+1; for ( i=0 ; iargnum ; i++ ) { if ( i>0 ) { fprintf(fw,","); w++; } fprintf(fw,"."); w++; } fprintf(fw,")"); w++; if ( pl->info != NULL && pl->info->description != NULL ) fprint_lfit_function_description(fw,width,w,16,pl->info->description); else fprintf(fw,"\n"); return(0); } else return(1); } int fprint_lfit_function_sublist(FILE *fw,int width,psnlfit *pl) { for ( ; pl->name != NULL ; pl++ ) { fprint_lfit_function_info(fw,width,pl); } return(0); } int fprint_lfit_function_list(FILE *fw,...) { va_list ap; int width; psnlfit *pl; #ifdef TIOCGWINSZ if ( isatty(fileno(fw)) ) { struct winsize ws; if ( ! ioctl(fileno(fw),TIOCGWINSZ,&ws) ) width=ws.ws_col-1; else width=0; } else #endif width=0; fprintf(fw,"# List of built-in operators and functions\n"); fprintf(fw,"# Name\t\tDescription\n"); fprintf(fw,"# [1]\t\t[2]\n"); va_start(ap,fw); while ( (pl=va_arg(ap,psnlfit *)) != NULL ) { fprint_lfit_function_sublist(fw,width,pl); } va_end(ap); return(0); } void exit_with_usage(int t) { if ( t ) fprint_error("%s",errmsgs[t]); else fprint_lfit_usage(stderr); exit(t); } /*****************************************************************************/ int lfit_register_symbol_exists(lfitpsnglobal *lpg,char *name) { char **s; int n; for ( s=lpg->symbols,n=lpg->nsymbol ; n>0 && s != NULL && (*s) != NULL ; s++,n-- ) { if ( strcmp((*s),name)==0 ) return(1); } return(0); } int lfit_register_symbol_add(lfitpsnglobal *lpg,char *name) { lpg->symbols=(char **)realloc(lpg->symbols,sizeof(char *)*(lpg->nsymbol+1)); lpg->symbols[lpg->nsymbol]=name; lpg->nsymbol++; return(0); } int lfit_register_check_code(lfitpsnglobal *lpg,int major) { psnprop *p; int n; for ( p=lpg->pl_prop,n=lpg->nprop ; n>0 && p != NULL && p->major>=0 ; p++,n-- ) { if ( p->major==major ) return(1); } return(0); } int lfit_register_function(char *name,int major,int argnum, int (*funct)(double *top_of_the_stack_pointer), short * diffrule, char * symevalstring) { if ( lfit_register_check_code(&lpg,major) ) { fprint_error("internal: registering function '%s': major code %d aready in use",name,major); return(1); } if ( major>=0 && name != NULL ) { lpg.pl_sym=(psnsym *)realloc(lpg.pl_sym,sizeof(psnsym)*(lpg.nsym+2)); lpg.pl_sym[lpg.nsym].type=T_FN; lpg.pl_sym[lpg.nsym].major=major; lpg.pl_sym[lpg.nsym].name=name; lpg.pl_sym[lpg.nsym].minor=argnum; memset(&lpg.pl_sym[lpg.nsym+1],0,sizeof(psnsym)); lpg.nsym++; lfit_register_symbol_add(&lpg,name); } if ( funct != NULL ) { lpg.pl_prop=(psnprop *)realloc(lpg.pl_prop,sizeof(psnprop)*(lpg.nprop+2)); lpg.pl_prop[lpg.nprop].major=major; lpg.pl_prop[lpg.nprop].argnum=argnum; lpg.pl_prop[lpg.nprop].precedency=0; lpg.pl_prop[lpg.nprop].associativity=0; memset(&lpg.pl_prop[lpg.nprop+1],0,sizeof(psnprop)); lpg.nprop++; lpg.pl_funct=(psnfunct *)realloc(lpg.pl_funct,sizeof(psnfunct)*(lpg.nfunct+2)); lpg.pl_funct[lpg.nfunct].major=major; lpg.pl_funct[lpg.nfunct].funct=funct; memset(&lpg.pl_funct[lpg.nfunct+1],0,sizeof(psnfunct)); lpg.nfunct++; } if ( diffrule != NULL ) { lpg.pl_diff=(psndiff *)realloc(lpg.pl_diff,sizeof(psndiff)*(lpg.ndiff+2)); lpg.pl_diff[lpg.ndiff].major=major; lpg.pl_diff[lpg.ndiff].oplist=diffrule; memset(&lpg.pl_diff[lpg.ndiff+1],0,sizeof(psndiff)); lpg.ndiff++; } if ( symevalstring != NULL ) { lpg.pl_symeval=(psnsymeval *)realloc(lpg.pl_symeval,sizeof(psnsymeval)*(lpg.nsymeval+2)); lpg.pl_symeval[lpg.nsymeval].major=major; lpg.pl_symeval[lpg.nsymeval].string=symevalstring; lpg.pl_symeval[lpg.nsymeval].strength=argnum; lpg.pl_symeval[lpg.nsymeval].affixation=0; memset(&lpg.pl_symeval[lpg.nsymeval+1],0,sizeof(psnsymeval)); lpg.nsymeval++; } return(0); } int lfit_register_operator(char *name,int major,int minor,int argnum, int precedency,int associativity, int (*funct)(double *top_of_the_stack_pointer), short * diffrule, char * symevalstring,int strength,int affixation) { if ( lfit_register_check_code(&lpg,major) ) { fprint_error("internal: registering operator '%s': major code %d aready in use",name,major); return(1); } if ( major>=0 && name != NULL ) { lpg.pl_sym=(psnsym *)realloc(lpg.pl_sym,sizeof(psnsym)*(lpg.nsym+2)); lpg.pl_sym[lpg.nsym].name=name; lpg.pl_sym[lpg.nsym].type=T_OP; lpg.pl_sym[lpg.nsym].major=major; lpg.pl_sym[lpg.nsym].minor=minor; memset(&lpg.pl_sym[lpg.nsym+1],0,sizeof(psnsym)); lpg.nsym++; lfit_register_symbol_add(&lpg,name); } if ( funct != NULL ) { lpg.pl_prop=(psnprop *)realloc(lpg.pl_prop,sizeof(psnprop)*(lpg.nprop+2)); lpg.pl_prop[lpg.nprop].major=major; lpg.pl_prop[lpg.nprop].argnum=argnum; lpg.pl_prop[lpg.nprop].precedency=precedency; lpg.pl_prop[lpg.nprop].associativity=associativity; memset(&lpg.pl_prop[lpg.nprop+1],0,sizeof(psnprop)); lpg.nprop++; lpg.pl_funct=(psnfunct *)realloc(lpg.pl_funct,sizeof(psnfunct)*(lpg.nfunct+2)); lpg.pl_funct[lpg.nfunct].major=major; lpg.pl_funct[lpg.nfunct].funct=funct; memset(&lpg.pl_funct[lpg.nfunct+1],0,sizeof(psnfunct)); lpg.nfunct++; } if ( diffrule != NULL ) { lpg.pl_diff=(psndiff *)realloc(lpg.pl_diff,sizeof(psndiff)*(lpg.ndiff+2)); lpg.pl_diff[lpg.ndiff].major=major; lpg.pl_diff[lpg.ndiff].oplist=diffrule; memset(&lpg.pl_diff[lpg.ndiff+1],0,sizeof(psndiff)); lpg.ndiff++; } if ( symevalstring != NULL ) { lpg.pl_symeval=(psnsymeval *)realloc(lpg.pl_symeval,sizeof(psnsymeval)*(lpg.nsymeval+2)); lpg.pl_symeval[lpg.nsymeval].major=major; lpg.pl_symeval[lpg.nsymeval].string=symevalstring; lpg.pl_symeval[lpg.nsymeval].strength=strength; lpg.pl_symeval[lpg.nsymeval].affixation=affixation; memset(&lpg.pl_symeval[lpg.nsymeval+1],0,sizeof(psnsymeval)); } return(0); } int lfit_register_internal(psnlfit *pl) { int ret; if ( pl->type==T_OP ) { ret=lfit_register_operator(pl->name,pl->major,pl->minor,pl->argnum, pl->precedency,pl->associativity, pl->funct, pl->diff, pl->string,pl->strength,pl->affixation); } else if ( pl->type==T_FN ) { ret=lfit_register_function(pl->name,pl->major,pl->argnum, pl->funct, pl->diff, pl->string); } else ret=2; return(ret); } /*****************************************************************************/ int is_verbose; /*****************************************************************************/ typedef struct { FILE *f_write; /* [-o ] default output */ FILE *f_lused; /* [-of] used lines */ FILE *f_lrejd; /* [-or] rejected lines */ FILE *f_lall; /* [-oa] all lines */ FILE *f_expr; /* [-ox] expression */ FILE *f_vval; /* [-ov] variable=value args. */ } fitout; #define FIT_METHOD_NONE 0 /* no fitting, just evaluation */ #define FIT_METHOD_CLLS 1 /* classical linear least squares */ #define FIT_METHOD_NLLM 2 /* nonlinear Levenberg-Marquardt */ #define FIT_METHOD_MCMC 3 /* Markov Chain Monte-Carlo */ #define FIT_METHOD_MCHI 4 /* mapping of chi^2 space on a grid */ #define FIT_METHOD_EMCE 5 /* Monte-Carlo error estimation */ #define FIT_METHOD_DHSX 6 /* downhill simplex */ #define FIT_METHOD_XMMC 7 /* extended Markov Chain Monte-Carlo */ #define FIT_METHOD_LMND 8 /* L-M with numerical derivatives */ #define FIT_METHOD_FIMA 9 /* Fisher information matrix analysis*/ typedef struct { int fit_method; /* see FIT_METHOD_* definitions above */ int niter; /* number of sigmareject iterations */ double sigma; /* rejection level in the units of std dev */ int mc_iterations; /* EMCE/MCMC/XMMC iterations */ struct { struct { int use_fisher_sx; /* use inital Fisher simplex */ } dhsx; struct { int sub_method; /* fit method of the substeps*/ int skip_initial_fit; /* skip initial EMCE fit */ } emce; struct { double lambda, /* initial \lambda */ lambda_mpy; /* \lambda multiplier... */ int max_iter; /* max LM iterations */ int numeric_derivs; /* LMND vs. NLLM */ } nllm; struct { int do_montecarlo; /* do a MC dataset */ int write_original; /* write original values */ int write_uncert; /* write uncertainties */ int write_correl; /* write correlation matrix */ } fima; struct { int use_gibbs; /* do use Gibbs sampler */ int count_accepted; /* count accepted transitions*/ } mcmc; struct { int skip_initial_fit; /* skip initial (dhsx) fit */ int is_adaptive; /* use adaptive XMMC */ int count_accepted; /* count accepted transitions*/ int window; /* autocorr. length window */ int niter; /* additional iterations */ } xmmc; } tune; /* this is not an union since some complex methods */ /* require more parameter sets (e.g. EMCE+NLLM) */ } fitparam; typedef struct { int nc; /* total number of linear constraints*/ double **cmatrix; /* [nc]x[nvar] matrix of lin. constrs*/ double *cvector; /* [nvar] vector of constraint values*/ double **invlmatrix; /* inverse of the [nc+nvar]x[nc+nvar]*/ /* matrix (Lagrange-multiplicators) */ double **cproject; /* constraint projection matrix */ } fitconstraint; typedef struct { psn *funct; /* function describing the constraint*/ int ctype; /* type */ } dcfunct; typedef struct { int ndcfunct; /* number of domain constraints */ dcfunct *dcfuncts; } domconstraint; #define VAR_IS_CONSTANT 0x01 /* is it only a constant? */ #define VAR_MIN 0x02 /* MCMC minimal value is set & used */ #define VAR_MAX 0x04 /* MCMC maximal value is set & used */ #define VAR_STEP 0x08 /* chi2 mapping grid resolution */ #define VAR_ERR 0x10 /* has an initial error be defined? */ typedef struct { char *name; /* name of the variable to be fitted */ char format[16]; /* (*)printf-like output format */ double init; /* initial value (used by NLLM, DHSX, *MC) */ double ierr; /* initial error (used by MCMC, DHSX) */ double imin,imax; /* allowed range: minimal and maximal values */ double istp; /* grid step of the chi2 mapping */ double diff; /* difference used by LMND (or EMCE+LMND) */ int flags; /* some flags (see VAR_*) */ int is_linear; /* all of the functions linear in this var...*/ int is_separated; /* ..., and if so, separate this variable */ } variable; typedef struct { char *name; /* name of the derived variable */ char format[16]; /* (*)printf-like output format */ char *expr; /* expression for definition function */ psn *funct; /* definition function */ psn **diff; /* partial derivatives with respect to */ /* the (fitted) variables */ } dvariable; typedef struct { char *name; /* the name of the given column */ } column; typedef struct { char format[16]; /* *printf like output format */ } dumpexpr; typedef struct { int dbidx; /* data block index respecting to this row */ char *line; /* orig. input line (as read from the file) */ double *x; /* pointer to the numeric column data */ } fitinputrow; typedef struct { char *key; /* of the given data block */ char *colarg, /* -c ... */ *fncarg, /* -f ... */ *deparg, /* -y ... */ *errarg, /* -e ... or -w ... */ *inparg; /* -i ... */ int errtype; /* -e (error, 0) or -w (weight, !0) ? */ int ncol; /* number of columns (derived from colarg) */ column *cols; /* column specifications (i.e. names) */ psnsym *colsym; /* column symbols for the given data block */ psn *funct, /* PSN sequence of the function to be fitted */ *functorig, /* original (affine but nonlinear) version */ **diff; /* partial derivatives of the function */ lfitfunction *lfunct; int *map_var; int *map_idv; psn *dep, /* PSN sequence of dependent expression (-y) */ *err; /* PSN sequence of the error/weight expr. */ int *fchain; /* argument chain for 'funct' */ int is_linear; /* is 'funct' linear in the fit variables? */ int offset; /* offset of the related data in the arraies */ int size; /* number of related data rows... */ double dbscatter; /* scatter (RMS) respecting to the datablock */ double dbredchi2; /* reduced chi2 value resp to the datablk */ double xnoise; /* extra (red?) noise added by the EMCE */ } datablock; typedef struct { char corrfm[16]; /* correlation format (printf-like) */ psnsym *varsym; /* variable symbol information */ datablock *datablocks; /* individual data blocks [DBs] */ int ndatablock; /* number of data blocks */ int is_linear; /* are all of the functions linear? */ int maxncol; /* max number of columns of each DBs */ fitparam parameters; /* general fit parameters */ fitconstraint fconstraint; /* fit constraints */ domconstraint dconstraint; /* domain constraints (for MC) */ } lfitdata; typedef struct { int nvar; double *wvars; psnfunct *functs; lfitdata *lf; } fitfunctdata; typedef struct { char *file; void *handle; } lfitdynlib; /*****************************************************************************/ char *key_seek_real_position(char *key,int chrskip) { if ( key==NULL ) return(NULL); else if ( chrskip>=0 ) return(key+chrskip); else if ( *key != '-' ) return(key); else if ( *(key+1) != '-' ) return(key+2); else { key+=2; while ( *key && *key != '-' ) key++; if ( ! (*key) ) return(NULL); key++; return(key); } } int key_add_list(char ***rkeys,int *rnkey,char **klist,int chrskip) { char **keys,**p,*key; int i,nkey; keys=*rkeys; nkey=*rnkey; for ( p=klist ; klist != NULL && (*p) ; p++ ) { key=(*p)+chrskip; if ( ! (*key) ) continue; for ( i=0 ; idatablocks ; indatablock ; i++,db++ ) { if ( strcmp(db->key,key)==0 ) return(db); } return(NULL); } /*****************************************************************************/ /* constraint_initialize_lambda_matrix(): This function initializes the force matrix 'invlmatrix' which is used by constraint_force(). The matrix 'invlmatrix' should be pre-allocated and must have a size of [nc+nvar] x [nc+nvar] */ int constraint_initialize_lambda_matrix(int nc,int nvar, double **cmatrix,double **invlmatrix) { int i,j; double **lmatrix; lmatrix=invlmatrix; for ( i=0 ; iterms,c=0 ; seq->type ; seq++,c++ ) { if ( (n=chain[c])<0 ) continue; w=&pseq->terms[n]; if ( ! ( w->type==T_OP || w->type==T_FN ) ) chain[c]=-1; else if ( ! ( w->major==O_MUL || w->major==O_DIV ) ) chain[c]=-1; else if ( ! ( n>c+1) ) chain[c]=-1; } return(0); } #define PSNSTACKBLOCK 64 int lfit_psn_double_calc(psn *pseq,int *chain,psnfunct *flist, double *result,double *vars) { double stack_automatic[PSNSTACKBLOCK],*stack_dynamic,*stack; int i,nopt,narg,sp,c,n; psnterm *seq; int stacklen; stack=stack_automatic; stack_dynamic=NULL; stacklen=PSNSTACKBLOCK; nopt=0;sp=0; for ( seq=pseq->terms,c=0 ; seq->type ; seq++,c++ ) { switch( seq->type ) { case T_CONST: stack[sp]=pseq->cons[seq->major],sp++; break; case T_VAR: stack[sp]=vars[seq->major],sp++; break; case T_SCONST: stack[sp]=(double)(seq->major),sp++; break; case T_STACKVAR: stack[sp]=stack[seq->major],sp++; if ( seq->major+1>nopt ) nopt=seq->major+1; break; case T_OP: case T_FN: if ( seq->major >= LFIT_F_MAX_BUILTIN ) { lffreg *lr; double ret; narg=seq->minor; i=seq->cache; if ( i<0 ) { for ( i=0 ; imajor && seq->major < lpg.lffregs[i].nmajor ) break; } if ( lpg.nlffreg <= i ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENOTFOUND); } seq->cache=i; } lr=&lpg.lffregs[i]; i=seq->major-lr->fmajor; if ( i==0 ) { double x; if ( lr->lff->function(stack+sp-(lr->lff->nvar+lr->lff->nidv),stack+sp-(lr->lff->nidv),&x,NULL) ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENUMERICAL); } ret=x; /* fprintf(stderr,"ret=%g\n",ret); */ } else if ( i>0 ) { if ( lr->diff==NULL ) lr->diff=(double *)malloc(sizeof(double)*lr->lff->nvar); if ( lr->lff->function(stack+sp-(lr->lff->nvar+lr->lff->nidv),stack+sp-(lr->lff->nidv),&ret,lr->diff) ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENUMERICAL); } ret=lr->diff[i-1]; } else ret=0.0; sp-=narg; stack[sp]=ret; sp++; break; } switch ( seq->major ) { case O_ADD: sp--;stack[sp-1]+=stack[sp]; break; case O_SUB: sp--;stack[sp-1]-=stack[sp]; break; case O_MUL: sp--;stack[sp-1]*=stack[sp]; break; case O_DIV: if ( stack[sp-1]==0.0 ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENUMERICAL); } sp--;stack[sp-1]/=stack[sp]; break; case O_POW: sp--;stack[sp-1]=pow(stack[sp-1],stack[sp]); break; case O_CHS: stack[sp-1]=-stack[sp-1]; break; case O_RCP: if ( stack[sp-1]==0.0 ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENUMERICAL); } stack[sp-1]=1.0/stack[sp-1]; break; case O_PSQ: stack[sp-1]*=stack[sp-1]; break; case F_SQR: if ( stack[sp-1]<0.0 ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENUMERICAL); } stack[sp-1]=sqrt(stack[sp-1]); break; default: narg=seq->minor; i=seq->cache; if ( i<0 ) { i=psn_cache_search(seq->major,flist); if ( i<0 ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENOTFOUND); } seq->cache=i; } if ( flist[i].funct(stack+sp) ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENUMERICAL); } sp+=1-narg; break; } break; } while ( chain != NULL && (n=chain[c])>=0 && stack[sp-1]==0.0 ) { seq=&pseq->terms[n]; for ( ; c<=n ; c++ ) { if ( pseq->terms[c].type==T_STACKVAR && pseq->terms[c].major+1>nopt ) nopt=pseq->terms[c].major+1; } c=n; } if ( sp>=stacklen ) { if ( stacklen==PSNSTACKBLOCK ) { int i; stacklen+=PSNSTACKBLOCK; stack_dynamic=(double *)malloc(sizeof(double)*stacklen); for ( i=0 ; i=0.0 ) fprintf(fw,"%12.5f\n",chi2); else fprintf(fw,"\n"); return(0); } int fprint_variable_name_list(FILE *fw,variable *vars,int nvar) { int i,w,l; char *format; for ( i=0 ; i0 ; n/=10 ) d++; return(d); } int fprint_variable_name_index(FILE *fw,variable *vars,int nvar) { int i,w,l; char *format; for ( i=0 ; ilf->datablocks[fir->dbidx]; if ( db->funct != NULL ) { for ( i=0 ; invar ; i++ ) { ffd->wvars[i]=a[i]; } ncol=db->ncol; for ( i=0 ; iwvars[i+ffd->nvar]=fir->x[i]; } if ( ry != NULL ) { lfit_psn_double_calc(db->funct,db->fchain,ffd->functs,ry,ffd->wvars); /* fprintf(stderr,"y=%g\n",(*ry)); */ } if ( rdy != NULL ) { for ( i=0 ; invar ; i++ ) { lfit_psn_double_calc(db->diff[i],NULL,ffd->functs,&rdy[i],ffd->wvars); /* fprintf(stderr,"dy[%d]=%g\n",i,rdy[i]); */ } } } else if ( db->lfunct != NULL ) { for ( i=0 ; ilfunct->nvar ; i++ ) { ffd->wvars[i]=a[db->map_var[i]]; } for ( i=0 ; ilfunct->nidv ; i++ ) { ffd->wvars[i+ffd->nvar]=fir->x[db->map_idv[i]]; } db->lfunct->function(ffd->wvars,ffd->wvars+ffd->nvar,ry,rdy); if ( rdy != NULL ) { for ( i=0 ; invar ; i++ ) { ffd->wvars[i]=0.0; } for ( i=0 ; ilfunct->nvar ; i++ ) { ffd->wvars[db->map_var[i]]=rdy[i]; } memcpy(rdy,ffd->wvars,sizeof(double)*ffd->nvar); } } } /* fit_function_optional_derivatives(): Same as above but not all of the partial derivatives are evaluated. */ void fit_function_optional_derivatives(void *x,double *a,double *ry,double *rdy,void *param, int nidx,int *idxs) { int i,j,ncol; datablock *db; fitfunctdata *ffd=(fitfunctdata *)param; fitinputrow *fir=(fitinputrow *)x; if ( nidx<=0 || idxs==NULL || rdy==NULL ) /* imply no request */ { rdy=NULL; nidx=0; idxs=NULL; } db=&ffd->lf->datablocks[fir->dbidx]; if ( db->funct != NULL ) { for ( i=0 ; invar ; i++ ) { ffd->wvars[i]=a[i]; } ncol=db->ncol; for ( i=0 ; iwvars[i+ffd->nvar]=fir->x[i]; } if ( ry != NULL ) { lfit_psn_double_calc(db->funct,db->fchain,ffd->functs,ry,ffd->wvars); } for ( j=0 ; jdiff[i],NULL,ffd->functs,&rdy[i],ffd->wvars); } } /* well, yes, the lfit external API does not support specifications for optional derivatives, so this is the same as in fit_function(). */ else if ( db->lfunct != NULL ) { for ( i=0 ; ilfunct->nvar ; i++ ) { ffd->wvars[i]=a[db->map_var[i]]; } for ( i=0 ; ilfunct->nidv ; i++ ) { ffd->wvars[i+ffd->nvar]=fir->x[db->map_idv[i]]; } db->lfunct->function(ffd->wvars,ffd->wvars+ffd->nvar,ry,rdy); if ( rdy != NULL ) { for ( i=0 ; invar ; i++ ) { ffd->wvars[i]=0.0; } for ( i=0 ; ilfunct->nvar ; i++ ) { ffd->wvars[db->map_var[i]]=rdy[i]; } memcpy(rdy,ffd->wvars,sizeof(double)*ffd->nvar); } } } /*****************************************************************************/ int write_fit_results(fitout *off,int errdump,double *bvector,double *evector, int nvar,int nrow,int resdump,int is_dump_delta, void **fitpnt,double *fiteval,fitfunctdata *ffd, double *fitwght,double *fitdep,fitinputrow *fitinputrows, lfitdata *lf,variable *vars) { int i; if ( off->f_write != NULL ) { switch ( errdump ) { case 1: fwrite_vars(off->f_write,bvector,vars,nvar); fprintf(off->f_write,"\n"); fwrite_vars(off->f_write,evector,vars,nvar); fprintf(off->f_write,"\n"); break; case 2: for ( i=0 ; if_write,vars[i].format,bvector[i]); fprintf(off->f_write," "); fprintf(off->f_write,vars[i].format,evector[i]); fprintf(off->f_write," "); } fprintf(off->f_write,"\n"); break; case 3: for ( i=0 ; if_write,"%11g %11g\n",bvector[i],evector[i]); } break; default: fwrite_vars(off->f_write,bvector,vars,nvar); fprintf(off->f_write,"\n"); break; } if ( resdump>=0 ) { double d,sdd,sig,w; sdd=0.0; for ( i=0 ; invar ) sdd/=(double)(nrow-nvar); else sdd=0.0; } else sdd/=(double)nrow; if ( resdump & RESIDUAL_CHI2 ) sig=sdd; else sig=sqrt(sdd); fprintf(off->f_write,"%11g\n",sig); } } for ( i=0 ; if_lused != NULL || off->f_lrejd != NULL || off->f_lall != NULL ) ; i++ ) { double delta; int is_last_in_block; if ( if_lused != NULL && fitwght[i]>0.0 ) { fprintf(off->f_lused,"%s",fitinputrows[i].line); if ( is_dump_delta<0 ) fprintf(off->f_lused," ## %12g",delta); if ( is_dump_delta>0 ) fprintf(off->f_lused," %12g",delta); fprintf(off->f_lused,"\n"); if ( is_last_in_block ) fprintf(off->f_lused,"\n"); } if ( off->f_lrejd != NULL && fitwght[i]<=0.0 ) { fprintf(off->f_lrejd,"%s",fitinputrows[i].line); if ( is_dump_delta<0 ) fprintf(off->f_lrejd," ## %12g",delta); if ( is_dump_delta>0 ) fprintf(off->f_lrejd," %12g",delta); fprintf(off->f_lrejd,"\n"); if ( is_last_in_block ) fprintf(off->f_lrejd,"\n"); } if ( off->f_lall != NULL ) { fprintf(off->f_lall,"%s",fitinputrows[i].line); if ( is_dump_delta<0 ) fprintf(off->f_lall," ## %12g",delta); if ( is_dump_delta>0 ) fprintf(off->f_lall," %12g",delta); fprintf(off->f_lall,"\n"); if ( is_last_in_block ) fprintf(off->f_lall,"\n"); } } if ( off->f_expr != NULL ) { char *functstr; int fmajor,i,r,d; psnterm *p; psn *pf; datablock *db; psnsym *mysyms[8]; mysyms[0]=lf->varsym, mysyms[1]=NULL, mysyms[2]=lpg.pl_sym, mysyms[3]=NULL; for ( d=0 ; dndatablock ; d++ ) { db=&lf->datablocks[d]; mysyms[1]=db->colsym; pf=db->functorig; for ( i=0,fmajor=0 ; iterms ; interm ; i++,p++ ) { if ( p->type==T_VAR && p->majortype=T_CONST; p->major=fmajor+p->major; p->minor=0; p->cache=0; } } functstr=psn_convert_symbolic(pf,lpg.pl_prop,lpg.pl_symeval,mysyms,NULL); if ( functstr != NULL ) { fprintf(off->f_expr,"%s\n",functstr); free(functstr); } else fprintf(off->f_expr,"-\n"); } } if ( off->f_vval != NULL ) { for ( i=0 ; if_vval,"%s=%g",vars[i].name,bvector[i]); if ( if_vval,","); else fprintf(off->f_vval,"\n"); } } return(0); } char ** read_fit_file(FILE *fr) { char **lines,*cline; int i,ln; ln=0; lines=NULL; while ( ! feof(fr) ) { cline=freadline(fr); if ( cline==NULL ) break; for ( i=0 ; cline[i] ; ) { if ( cline[i]==13 || cline[i]==10 ) cline[i]=0; else i++; } lines=(char **)realloc(lines,sizeof(char *)*(ln+1)); lines[ln]=cline; ln++; } lines=(char **)realloc(lines,sizeof(char *)*(ln+1)); lines[ln]=NULL; ln++; return(lines); } int read_fit_data(FILE *fr,char **lines,int dbidx,column *cols,int ncol, int nvar,int *rnrow,int maxncol, double **rfitdata,double **rfitdep,double **rfitwght,fitinputrow **rfitinputrows, psn *pdep,psn *perr,int errtype) { int ln,nrow,cnc,i,j,is_cont; double *fitdata,*fitdep,*fitwght; fitinputrow *fitinputrows; char *rbuff,**lvarstr,*cline; double f,weight; double *wvars,*lvars; if ( fr == NULL && lines == NULL ) return(-1); else if ( fr != NULL && lines != NULL ) return(-1); wvars=(double *)malloc(sizeof(double)*(nvar+maxncol)); lvars=(double *)malloc(sizeof(double)*(nvar+maxncol)); nrow=*rnrow; fitdata =*rfitdata; fitdep =*rfitdep; fitwght =*rfitwght; fitinputrows=*rfitinputrows; rbuff=NULL;lvarstr=NULL; ln=0; while ( (fr != NULL && ! feof(fr)) || (lines != NULL && lines[ln] != NULL) ) { ln++; if ( rbuff != NULL ) { free(rbuff); rbuff=NULL; } if ( lvarstr != NULL ) { free(lvarstr);lvarstr=NULL; } if ( fr != NULL ) rbuff=freadline(fr); else rbuff=strdup(lines[ln-1]); if ( rbuff==NULL ) break; cline=strdup(rbuff); /* parsing, token extaction, ...: */ for ( i=0 ; cline[i] ; ) { if ( cline[i]==13 || cline[i]==10 ) cline[i]=0; else i++; } for ( i=0 ; i=0 ) fprint_warning("missing column in line %d, skipped",ln); free(cline); continue; } /* we check the used columns for valid (numerical) content: */ is_cont=0; for ( i=0 ; i=0 ) fprint_warning("inappropriate field '%s' in line %d, skipped",lvarstr[i],ln); is_cont=1; } } else lvars[i]=0.0; } if ( is_cont ) { free(cline); continue; } for ( i=0 ; i0.0 ) weight=1.0/f; /* sigma... */ else weight=0.0; /* unexpected*/ /* if ( ! errtype ) weight=1.0/f; else weight=f; */ } else weight=1.0; /*if ( weight == 0.0 ) continue;*/ /* evaluating the current term: */ lfit_psn_double_calc(pdep,NULL,lpg.pl_funct,&f,wvars); fitdata =(double *)realloc(fitdata ,(nrow+1)*sizeof(double)*(maxncol)); fitdep =(double *)realloc(fitdep ,(nrow+1)*sizeof(double)); fitwght =(double *)realloc(fitwght ,(nrow+1)*sizeof(double)); fitinputrows=(fitinputrow *)realloc(fitinputrows,(nrow+1)*sizeof(fitinputrow)); j=(nrow)*(maxncol); for ( i=0 ; indatablock ; d++ ) { db=&lf->datablocks[d]; if ( db->inparg==NULL || strcmp(db->inparg,"-")==0 ) nstdin++; } if ( nstdin >= 2 ) stdinlines=read_fit_file(stdin); else stdinlines=NULL; for ( d=0 ; dndatablock ; d++ ) { db=&lf->datablocks[d]; db->offset=*rnrow; if ( db->inparg==NULL || strcmp(db->inparg,"-")==0 ) { if ( stdinlines != NULL ) { lines=stdinlines; fr=NULL; } else { lines=NULL; fr=stdin; } } else { fr=fopen(db->inparg,"rb"); if ( fr==NULL ) { fprint_warning("unable to read file '%s' to read fit data",db->inparg); continue; } lines=NULL; } read_fit_data(fr,lines,d,db->cols,db->ncol,nvar,rnrow,lf->maxncol, rfitdata,rfitdep,rfitwght,rfitinputrows, db->dep,db->err,db->errtype); if ( fr != NULL && fileno(fr) != fileno(stdin) ) fclose(fr); db->size=(*rnrow)-db->offset; } if ( stdinlines != NULL ) { char **line; for ( line=stdinlines ; *line ; line++ ) { free(*line); } free(stdinlines); stdinlines=NULL; } return(0); } /* fit_linear_or_nonlinear(): This function is called fit_linear_or_nonlinear() because the cruical part of the whole thing is not the fit itself (even linear or nonlinear) but the 'auxiliary' stuff like reading/parsing the data, do the rejection, take into account the effects of the contstraints, whatsoever... The fitting is done in a standalone library, see lmfit.[ch]. */ int fit_linear_or_nonlinear(lfitdata *lf,fitout *off, variable *vars,int nvar,int errtype, int errdump,int resdump,int is_dump_delta,int is_weighted_sigma,int is_numeric_derivs) { int i,j,k,n,isig,nreject,nc; void **fitpnt; double *fitdata,*fitdep,*fiteval,*fitwght,lam,lam_mpy; double *wvars; fitinputrow *fitinputrows; int nrow; double **amatrix,*bvector,*evector,*xvector; fitfunctdata ffd; constraint ccstat,*cc; fitparam *fp; fp=&lf->parameters; if ( lf->fconstraint.nc>0 ) /* we have some constraints */ { nc= ccstat.nc= lf->fconstraint.nc; ccstat.cmatrix=lf->fconstraint.cmatrix; ccstat.cvector=lf->fconstraint.cvector; cc=&ccstat; } else /* we don't have any constraint */ { cc=NULL; nc=0; } fitdata =NULL; fitdep =NULL; fitwght =NULL; fitinputrows=NULL; nrow=0; read_all_fit_data(lf,nvar,&fitdata,&fitdep,&fitwght,&fitinputrows,&nrow); if ( nrow < nvar-nc ) { fprint_error("too few lines for fitting"); exit(1); } for ( i=0 ; imaxncol)); fitpnt=(void **)malloc(nrow*sizeof(void *)); for ( i=0 ; imaxncol]; fitpnt[i]=(void *)(&fitinputrows[i]); } ffd.nvar=nvar; ffd.wvars=wvars; ffd.functs=lpg.pl_funct; ffd.lf=lf; fiteval=(double *)malloc(sizeof(double)*nrow); for ( isig=0 ; isig<=fp->niter ; isig++ ) { if ( lf->is_linear ) { if ( errdump<=0 ) i=lin_fit_con(fitpnt,fitdep,bvector,fitwght,fit_function,nvar,nrow,&ffd,cc,NULL); else i=lin_fit_con(fitpnt,fitdep,bvector,fitwght,fit_function,nvar,nrow,&ffd,cc,evector); if ( i ) { fprint_error("singular matrix"); exit(1); } } else { for ( i=0 ; itune.nllm.lambda; lam_mpy=fp->tune.nllm.lambda_mpy; for ( n=0 ; ntune.nllm.max_iter ; n++ ) { if ( is_verbose>=2 ) { fwrite_vars(stderr,bvector,vars,nvar); fprintf(stderr,"(%11g)\n",lam); } if ( ! is_numeric_derivs) lam=nlm_fit_base_con(fitpnt,fitdep,bvector,fitwght,fit_function,nvar,nrow,&ffd,cc,lam,lam_mpy); else lam=nlm_fit_nmdf_con(fitpnt,fitdep,bvector,fitwght,fit_function,nvar,nrow,&ffd,cc,lam,lam_mpy,xvector); } } if ( isigniter ) { double d,s,sdd,sig,maxdev,w; s=sdd=0.0; for ( i=0 ; isigma; /*fprintf(stderr,"fp->sigma=%g\n",fp->sigma);*/ for ( i=0,j=0,k=0 ; i maxdev && fitwght[i]>0.0 ) { fitwght[i]=0.0; j++; } if ( fitwght[i]>0.0 ) k++; } nreject=j; if ( is_verbose>0 ) fprintf(stderr,"Iteration#%3d: rejected/be used/all: %4d/%4d/%4d\n",isig+1,j,k,nrow); } else nreject=0; if ( is_verbose>0 && fp->niter>0 && ( isig==fp->niter || nreject==0 ) ) { for ( i=0,k=0 ; i0.0 ) k++; } fprintf(stderr,"In the last : used/all: %4d/%4d\n",k,nrow); } if ( ! ( nreject>0 ) ) break; } if ( ! lf->is_linear ) errdump=0; write_fit_results(off,errdump,bvector,evector,nvar,nrow,resdump,is_dump_delta, fitpnt,fiteval,&ffd,fitwght,fitdep,fitinputrows,lf,vars); if ( fiteval != NULL ) free(fiteval); if ( fitpnt != NULL ) free(fitpnt); vector_free(xvector); vector_free(evector); vector_free(bvector); matrix_free(amatrix); if ( fitinputrows != NULL ) { for ( i=0 ; i 4 && (fabs(d[ip])+g) == fabs(d[ip]) && (fabs(d[iq])+g) == fabs(d[iq]) ) a[ip][iq]=0.0; else if ( fabs(a[ip][iq]) > tresh ) { h=d[iq]-d[ip]; if ( fabs(h)+g == fabs(h) ) t=(a[ip][iq])/h; else { theta=0.5*h/(a[ip][iq]); t=1.0/(fabs(theta)+sqrt(1.0+theta*theta)); if ( theta < 0.0 ) t=-t; } c=1.0/sqrt(1+t*t); s=t*c; tau=s/(1.0+c); h=t*a[ip][iq]; z[ip] -= h; z[iq] += h; d[ip] -= h; d[iq] += h; a[ip][iq]=0.0; for ( j=0 ; j0 ) i--; else i++; } else i++; } for ( i=0 ; i0 ) i--; else i++; } else i++; } for ( i=0 ; ilf->ndatablock; lchi=(chistat *)malloc(sizeof(chistat)*ndatablock); for ( i=0 ; idbidx].chi+=dy*dy; lchi[fir->dbidx].n++; } } else { for ( i=0 ; idbidx].chi+=dy*dy; lchi[fir->dbidx].n++; } } chi2=0.0; n=0; for ( i=0 ; ilf->ndatablock; lchi=(chistat *)malloc(sizeof(chistat)*ndatablock); for ( i=0 ; idbidx].chi+=dy*dy; lchi[fir->dbidx].n++; } } else { for ( i=0 ; idbidx].chi+=dy*dy; lchi[fir->dbidx].n++; } } chi2=0.0; n=0; for ( i=0 ; ilf->ndatablock; lchi=(chistat *)malloc(sizeof(chistat)*ndatablock); for ( i=0 ; i> %12g\n",dy); */ de=dy*fitwght[i]; lchi[fir->dbidx].sct+=dy*dy; lchi[fir->dbidx].chi+=de*de; lchi[fir->dbidx].n++; } for ( i=0 ; i 0 ) { ffd->lf->datablocks[i].dbscatter=sqrt(lchi[i].sct/lchi[i].n); ffd->lf->datablocks[i].dbredchi2=sqrt(lchi[i].chi/lchi[i].n); } else { ffd->lf->datablocks[i].dbscatter=0.0; ffd->lf->datablocks[i].dbredchi2=0.0; } } free(lchi); return(0); } double **data_get_inversecovariance(void **fitpnt,double *fitdep,double *fitwght, int nrow,int nvar,double *bvector,fitfunctdata *ffd) { double y,*dy,**cmatrix,isig2; int i,k,l; cmatrix=matrix_alloc(nvar); dy=vector_alloc(nvar); for ( k=0 ; klf->fconstraint.nc>0 ) { double **t1,**t2; int i,j,k; t1=matrix_alloc(nvar); t2=matrix_alloc(nvar); for ( i=0 ; ilf->fconstraint.cproject[k][j]; } } } for ( i=0 ; ilf->fconstraint.cproject[i][k]*t1[k][j]; } } } matrix_free(icmatrix); icmatrix=matrix_inverse_normal(t2,nvar,nvar-ffd->lf->fconstraint.nc); matrix_free(t2); matrix_free(t1); return(icmatrix); } else { if ( invert_gauss(icmatrix,nvar) ) { matrix_free(icmatrix); /* singular: fit is degenerated! */ return(NULL); } else return(icmatrix); } } complex * data_get_noise_dft(void **fitpnt,double *fitdep,double *fitwght,double *fiteval, int nrow,double *bvector,fitfunctdata *ffd) { double dy; int i,d,ndatablock; datablock *db; complex *res; ndatablock=ffd->lf->ndatablock; res=(complex *)malloc(sizeof(complex)*nrow); for ( i=0 ; ilf->datablocks[d]; pbfft_conv(res+db->offset,db->size,0); } return(res); } int data_perturb_wtn(void **fitpnt,double *fiteval,double *fitvary,int nrow,fitfunctdata *ffd) { int i; fitinputrow *fir; double noise; datablock *db; for ( i=0 ; ilf->datablocks[fir->dbidx]; noise=db->dbscatter; if ( db->xnoise>0.0 ) noise=sqrt(noise*noise+db->xnoise*db->xnoise); fitvary[i]=get_gaussian(fiteval[i],noise); } return(0); } int data_perturb_dft(void **fitpnt,double *fiteval,double *fitvary,int nrow,fitfunctdata *ffd, complex *resdft) { int d,i; fitinputrow *fir; double noise,pc,ps,phase,mul; datablock *db; complex *prtift; prtift=(complex *)malloc(sizeof(complex)*nrow); for ( i=0 ; ilf->ndatablock ; d++ ) { db=&ffd->lf->datablocks[d]; pbfft_conv(prtift+db->offset,db->size,1); } mul=sqrt(2.0); for ( i=0 ; ilf->datablocks[fir->dbidx]; if ( db->xnoise>0.0 ) noise=get_gaussian(0,db->xnoise); else noise=0.0; fitvary[i]=fiteval[i]+mul*prtift[i].re/db->size+noise; } free(prtift); return(0); } int find_chi2_errors(void **fitpnt,double *fitdep,double *fitwght, int nrow,double *bvector,fitfunctdata *ffd, variable *vars,int nvar, double *errleft,double *erright,double cchi) { int i,sign,k; double chi2; double *dvector,delta,dmin,dmax; dvector=vector_alloc(nvar); for ( i=0 ; i 0.0 ) { dmin=delta; for ( k=0 ; k<50 ; k++ ) { dvector[i]=bvector[i]+sign*dmin; chi2=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,dvector,ffd,1); if ( chi20.0 ; k++ ) { dvector[i]=bvector[i]+sign*dmax; chi2=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,dvector,ffd,1); if ( chi2>cchi ) break; dmax=dmax*2; } if ( k==50 ) delta=0.0; for ( k=0 ; k<20 && delta>0.0 ; k++ ) { delta=(dmin+dmax)/2.0; dvector[i]=bvector[i]+sign*delta; chi2=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,dvector,ffd,1); if ( chi2>cchi ) dmax=delta; else dmin=delta; } } if ( sign<0 ) errleft[i]=delta; else erright[i]=delta; } dvector[i]=bvector[i]; } vector_free(dvector); return(0); } /* fit_markov_chain_monte_carlo(): This function is the core of the Markov-chain Monte Carlo (MCMC) method. */ int fit_markov_chain_monte_carlo(lfitdata *lf,fitout *off,variable *vars,int nvar) { int i,n,nc,nrc,ccnt,is_not_accepted; void **fitpnt; double *fitdata,*fitdep,*fiteval,*fitwght; double *wvars,chi2,nchi,mchi,vx,u,alpha,dalpha; fitinputrow *fitinputrows; int nrow,cgibbs; double *bvector,*dvector,*evector,*mvector; fitfunctdata ffd; FILE *fw; fitparam *fp; fp=&lf->parameters; nc=lf->fconstraint.nc; /* number of constraints */ nrc=nc; /* number of "real" constraints, i.e. not explicit fixations */ for ( i=0 ; imaxncol)); fitpnt=(void **)malloc(nrow*sizeof(void *)); for ( i=0 ; imaxncol]; fitpnt[i]=(void *)(&fitinputrows[i]); } ffd.nvar=nvar; ffd.wvars=wvars; ffd.functs=lpg.pl_funct; ffd.lf=lf; fiteval=(double *)malloc(sizeof(double)*nrow); for ( i=0 ; i 0 ) { for ( i=0 ; i0 ) { constraint_force(bvector,nvar,nc, lf->fconstraint.invlmatrix,lf->fconstraint.cvector); } } chi2=data_get_chisquare(fitpnt,fitdep,fitwght,fiteval,nrow,bvector,&ffd,0); mchi=chi2; for ( i=0 ; if_write; if ( fw != NULL ) fwrite_vars_chi2(fw,bvector,vars,nvar,chi2); /* reset the Gibbs auxiliary counter: */ cgibbs=0; /* we have fp->mc_iterations iterations in a single chain: */ for ( n=0 ; (lf->parameters.tune.mcmc.count_accepted?ccnt:n)mc_iterations ; n++ ) { /* we assume accaptance, i.e. not out-of-boundary data */ is_not_accepted=0; if ( ! fp->tune.mcmc.use_gibbs ) { for ( i=0 ; i vars[i].imax ) { is_not_accepted=1; /* o-o-b */ dvector[i]=vars[i].imax; } } else dvector[i]=bvector[i]; } } else { /* copy everything... */ for ( i=0 ; i vars[i].imax ) { is_not_accepted=1; dvector[i]=vars[i].imax; } /* increase Gibbs counter by one: */ cgibbs=(cgibbs+1)%nvar; } /* the next point is not accepted (i.e. it is an out of bound point) */ if ( is_not_accepted ) continue; /* again, constraints are forced to the variables: */ if ( nc > 0 ) { for ( i=0 ; i0 ) { constraint_force(dvector,nvar,nc, lf->fconstraint.invlmatrix,lf->fconstraint.cvector); } } /* we get a new chi square value */ nchi=data_get_chisquare(fitpnt,fitdep,fitwght,fiteval,nrow,dvector,&ffd,0); /* just save it if it is minimal (useful as the fitted values) and */ /* to normalize the chisquare function (i.e. multiply the errors by */ /* some values if desired...) */ if ( nchi0.0 && (u=random_double()) <= alpha ) { for ( i=0 ; if_write != NULL ) { fw=off->f_write; if ( n>0 ) { alpha=(double)ccnt/(double)n; dalpha=sqrt((double)ccnt)/(double)n; } else { alpha=0.0; dalpha=0.0; } fprintf(fw,"#\n"); fprintf(fw,"# Accepted transitions / total iterations: %d/%d\n",ccnt,n); fprintf(fw,"# Total acceptance ratio: %.5f +/- %.5f\n",alpha,dalpha); fprintf(fw,"#\n# chi^2 values:\n"); mchi=data_get_chisquare(fitpnt,fitdep,fitwght,fiteval,nrow,mvector,&ffd,1); fprintf(fw,"#\tminimal: %g\n",mchi); fprintf(fw,"# Appropriate values for this chi^2:\n# "); fwrite_vars(fw,mvector,vars,nvar); fprintf(fw,"\n"); } if ( fiteval != NULL ) free(fiteval); if ( fitpnt != NULL ) free(fitpnt); if ( fitinputrows != NULL ) { for ( i=0 ; i=axes[i].n ) break; t+=k*m; m*=axes[i].n; } if ( i >= ndim ) { if ( next<0 || griddata[t].chi2=ndim ) break; } griddata[igrid].next=next; for ( i=0 ; i=ndim ) break; igrid++; }; for ( i=0 ; i=ndim ) break; } solve_gauss(amatrix,bvector,fdim); for ( i=0 ; in=n; cm->curr=0; cm->imin=vars[i].imin; cm->istp=vars[i].istp; cm->varindex=i; ndim++; if ( ngrid ) ngrid=ngrid*cm->n; else ngrid=cm->n; } if ( ngrid>0 && ndim>0 ) griddata=(gridpoint *)malloc(sizeof(gridpoint)*ngrid); else griddata=NULL; bvector=vector_alloc(nvar); /* set of unknown variables */ read_all_fit_data(lf,nvar,&fitdata,&fitdep,&fitwght,&fitinputrows,&nrow); wvars=(double *)malloc(sizeof(double)*(nvar+lf->maxncol)); fitpnt=(void **)malloc(nrow*sizeof(void *)); for ( i=0 ; imaxncol]; fitpnt[i]=(void *)(&fitinputrows[i]); } ffd.nvar=nvar; ffd.wvars=wvars; ffd.functs=lpg.pl_funct; ffd.lf=lf; for ( i=0 ; if_write; while ( 1 ) { chi2=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,bvector,&ffd,1); if ( fw != NULL ) { fprintf(fw," "); fwrite_vars(fw,bvector,vars,nvar); fprintf(fw,"%12g\n",chi2); } if ( griddata != NULL ) griddata[igrid].chi2=chi2; for ( i=0 ; i= ndim ) break; igrid++; }; if ( griddata != NULL && fw != NULL ) { int k,s,v; int *mins,nmin; int bdist,b; double **mmatrix,*mvector,mscalar; map_chi2_downlink(axes,ndim,griddata); mins=NULL; map_chi2_partitions(griddata,ngrid,&mins,&nmin); mmatrix=matrix_alloc(ndim); mvector=vector_alloc(ndim); if ( nmin>1 ) fprintf(fw,"# %d minima found:\n",nmin); else fprintf(fw,"# %d minimum found:\n",nmin); for ( n=0 ; n0 ) ) { fprintf(fw,"#\t(boundary minimum, highly possible to be false)\n"); continue; } fprintf(fw,"#\t(distinct minimum, distance from boundary: %d)\n",bdist); fprintf(fw,"# - interpolated minimum:\n"); map_chi2_fit_minimum(axes,ndim,griddata,mins[n],3, mmatrix,mvector,&mscalar); fprintf(fw,"#"); for ( i=0 ; ifconstraint.nc; /* number of constraints */ nrc=nc; /* number of "real" constraints, i.e. not explicit fixations */ for ( i=0 ; i 0 ) { for ( i=0 ; i0 ) { constraint_force(mvector,nvar,nc, lf->fconstraint.invlmatrix,lf->fconstraint.cvector); } } mchi=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,mvector,ffd,1); decrease_error_counter=0; for ( n=0 ; n=max_decrease_rejection ) { decrease_error_counter=0; for ( i=0 ; i vars[i].imax ) { is_not_accepted=1; /* o-o-b */ dvector[i]=vars[i].imax; } } else dvector[i]=mvector[i]; } /* the next point is not accepted (i.e. it is an out of bound point) */ if ( is_not_accepted ) { decrease_error_counter++; continue; } /* again, constraints are forced to the variables: */ if ( nc > 0 ) { for ( i=0 ; i0 ) { constraint_force(dvector,nvar,nc, lf->fconstraint.invlmatrix,lf->fconstraint.cvector); } } /* we get a new chi square value */ nchi=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,dvector,ffd,1); /* if we do only downlink minimalization, we implicitly not accept */ /* all of the cases when the value of \chi^2 increases: */ if ( nchiidx != NULL && 0nseparated ) chi2=data_get_chisquare_separated_linear(ldd->fitpnt,ldd->fitdep,ldd->fitwght,NULL,ldd->nrow,bvector,ldd->ffd,1,ldd->nvar,ldd->idx,ldd->nseparated,NULL); else chi2=data_get_chisquare(ldd->fitpnt,ldd->fitdep,ldd->fitwght,NULL,ldd->nrow,bvector,ldd->ffd,1); return(chi2); } int get_error_matrix(double **ematrix,int nvar,double *evector,double **icmatrix,int nc,double **cproject) { double **pmp,**m1,**m2,w,*a,**rcmatrix; int i,j,k,nrot; double *eigenvalues,**eigenvectors; if ( ( evector==NULL && icmatrix==NULL ) || ( evector!=NULL && icmatrix!=NULL ) ) return(-1); if ( nc>0 ) { pmp=matrix_alloc(nvar); m1 =matrix_alloc(nvar); m2 =matrix_alloc(nvar); if ( icmatrix==NULL ) { for ( i=0 ; i0 ) i--; else i++; } else i++; } for ( i=0 ; i0.0 ) eigenvalues[i]=1.0/sqrt(eigenvalues[i]); else eigenvalues[i]=0.0; for ( j=0 ; jlf->fconstraint; if ( fc->nc>0 ) { constraint_force(mvector,nvar,fc->nc, fc->invlmatrix,fc->cvector); } for ( j=0 ; jparameters; nc=lf->fconstraint.nc; /* number of constraints */ nrc=nc; /* number of "real" constraints, i.e. not explicit fixations */ for ( i=0 ; ifconstraint.nc>0 ) /* we have some constraints */ { ccstat.nc= lf->fconstraint.nc; ccstat.cmatrix=lf->fconstraint.cmatrix; ccstat.cvector=lf->fconstraint.cvector; cc=&ccstat; } else /* we don't have any constraint */ cc=NULL; fitdata =NULL; fitdep =NULL; fitwght =NULL; fitinputrows=NULL; nrow=0; bvector=vector_alloc(nvar); /* set of unknown variables */ dvector=vector_alloc(nvar); /* perturbed variable vector */ evector=vector_alloc(nvar); /* error vector */ mvector=vector_alloc(nvar); /* vector of minimal values */ xvector=vector_alloc(nvar); /* vector for numerical derivatives */ read_all_fit_data(lf,nvar,&fitdata,&fitdep,&fitwght,&fitinputrows,&nrow); if ( nrow < nvar-nc ) { fprint_error("too few lines for fitting"); exit(1); } wvars=(double *)malloc(sizeof(double)*(nvar+lf->maxncol)); fitvary=(double *)malloc(nrow*sizeof(double)); fitpnt=(void **)malloc(nrow*sizeof(void *)); for ( i=0 ; imaxncol]; fitpnt[i]=(void *)(&fitinputrows[i]); } ffd.nvar=nvar; ffd.wvars=wvars; ffd.functs=lpg.pl_funct; ffd.lf=lf; fiteval=(double *)malloc(sizeof(double)*nrow); for ( i=0 ; itune.emce.sub_method==FIT_METHOD_DHSX ) { ematrix=matrix_alloc(nvar); get_error_matrix(ematrix,nvar,evector,NULL,lf->fconstraint.nc,lf->fconstraint.cproject); } else ematrix=NULL; if ( fp->tune.emce.skip_initial_fit ) mchi=-1; else if ( fp->tune.emce.sub_method==FIT_METHOD_CLLS ) { lin_fit_con(fitpnt,fitdep,mvector,fitwght, fit_function,nvar,nrow,&ffd,cc,NULL); mchi=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,mvector,&ffd,1); } else if ( fp->tune.emce.sub_method==FIT_METHOD_NLLM ) { double lam; lam=fp->tune.nllm.lambda; for ( i=0 ; itune.nllm.max_iter ; i++ ) { lam=nlm_fit_base_con(fitpnt,fitdep,mvector,fitwght, fit_function,nvar,nrow,&ffd,cc, lam,fp->tune.nllm.lambda_mpy); } mchi=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,mvector,&ffd,1); } else if ( fp->tune.emce.sub_method==FIT_METHOD_LMND ) { double lam; lam=fp->tune.nllm.lambda; for ( i=0 ; itune.nllm.max_iter ; i++ ) { lam=nlm_fit_nmdf_con(fitpnt,fitdep,mvector,fitwght, fit_function,nvar,nrow,&ffd,cc, lam,fp->tune.nllm.lambda_mpy,xvector); } mchi=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,mvector,&ffd,1); } else if ( fp->tune.emce.sub_method==FIT_METHOD_MCMC ) { mchi=find_monte_carlo_minimum(fitpnt,fitdep,fitwght,nrow,mvector,&ffd, evector,downlink_max_iter,max_decrease_rejection,decrease_error_ratio, lf,vars,nvar); } else /* FIT_METHOD_DHSX: default */ { mchi=find_downhill_simplex_minimum(fitpnt,fitdep,fitwght,nrow, mvector,&ffd,ematrix,nvar,nvar-nc,NULL,0); } data_get_scatters(fitpnt,fitdep,fitwght,fiteval, nrow,mvector,&ffd,0); if ( use_dft_rednoise ) resdft=data_get_noise_dft(fitpnt,fitdep,fitwght,fiteval, nrow,mvector,&ffd); else resdft=NULL; fw=off->f_write; if ( fw != NULL ) { fprintf(fw,"# Initial result (nonperturbed, original data):\n"); if ( mchi>=0.0 ) fwrite_vars_chi2(fw,mvector,vars,nvar,mchi); else { fwrite_vars_chi2(fw,mvector,vars,nvar,0.0); fprintf(fw,"# (explicitly untouched initial input values)\n"); } fprintf(fw,"# Scatters (RMS, reduced \\chi^2): \n"); for ( i=0 ; indatablock ; i++ ) { fprintf(fw,"# [%s] %12g %12.8f\n", lf->datablocks[i].key, lf->datablocks[i].dbscatter, lf->datablocks[i].dbredchi2); } if ( fp->mc_iterations>0 ) { fprintf(fw,"# Additional fits:\n"); } fflush(fw); } for ( n=0 ; nmc_iterations ; n++ ) { if ( resdft != NULL ) data_perturb_dft(fitpnt,fiteval,fitvary,nrow,&ffd,resdft); else data_perturb_wtn(fitpnt,fiteval,fitvary,nrow,&ffd); for ( i=0 ; itune.emce.sub_method==FIT_METHOD_CLLS ) { lin_fit_con(fitpnt,fitvary,bvector,fitwght,fit_function,nvar,nrow,&ffd,cc,NULL); nchi=data_get_chisquare(fitpnt,fitvary,fitwght,NULL,nrow,bvector,&ffd,1); } else if ( fp->tune.emce.sub_method==FIT_METHOD_NLLM ) { double lam; lam=fp->tune.nllm.lambda; for ( i=0 ; itune.nllm.max_iter ; i++ ) { lam=nlm_fit_base_con(fitpnt,fitvary,bvector,fitwght, fit_function,nvar,nrow,&ffd,cc,lam,fp->tune.nllm.lambda_mpy); } nchi=data_get_chisquare(fitpnt,fitvary,fitwght,NULL,nrow,bvector,&ffd,1); } else if ( fp->tune.emce.sub_method==FIT_METHOD_LMND ) { double lam; lam=fp->tune.nllm.lambda; for ( i=0 ; itune.nllm.max_iter ; i++ ) { lam=nlm_fit_nmdf_con(fitpnt,fitvary,bvector,fitwght, fit_function,nvar,nrow,&ffd,cc, lam,fp->tune.nllm.lambda_mpy,xvector); } nchi=data_get_chisquare(fitpnt,fitvary,fitwght,NULL,nrow,bvector,&ffd,1); } else if ( fp->tune.emce.sub_method==FIT_METHOD_MCMC ) { nchi=find_monte_carlo_minimum(fitpnt,fitvary,fitwght,nrow,bvector,&ffd, evector,downlink_max_iter,max_decrease_rejection,decrease_error_ratio, lf,vars,nvar); } else /* FIT_METHOD_DHSX: default */ { nchi=find_downhill_simplex_minimum(fitpnt,fitvary,fitwght,nrow, bvector,&ffd,ematrix,nvar,nvar-nc,NULL,0); } /* nchi=find_monte_carlo_minimum(fitpnt,fitvary,fitwght,nrow,bvector,&ffd, evector,downlink_max_iter,max_decrease_rejection,decrease_error_ratio, lf,vars,nvar); */ if ( fw != NULL ) { fwrite_vars_chi2(fw,bvector,vars,nvar,nchi); fflush(fw); } } if ( resdft != NULL ) free(resdft); if ( fiteval != NULL ) free(fiteval); if ( fitpnt != NULL ) free(fitpnt); if ( fitvary != NULL ) free(fitvary); if ( fitinputrows != NULL ) { for ( i=0 ; iparameters; nc=lf->fconstraint.nc; /* number of constraints */ nrc=nc; /* number of "real" constraints, i.e. not explicit fixations */ nseparated=0; for ( i=0 ; iparameters.tune.xmmc.window; corrlendd=matrix_alloc_gen(window,3*nvar); corr_ftmp=corrlendd+0*nvar; corr_prev=corrlendd+1*nvar; corr_carr=corrlendd+2*nvar; corr_sum1=vector_alloc(nvar); corr_sum2=vector_alloc(nvar); read_all_fit_data(lf,nvar,&fitdata,&fitdep,&fitwght,&fitinputrows,&nrow); if ( nrow < nvar-nc ) { fprint_error("too few lines for fitting"); exit(1); } wvars=(double *)malloc(sizeof(double)*(nvar+lf->maxncol)); fitpnt=(void **)malloc(nrow*sizeof(void *)); for ( i=0 ; imaxncol]; fitpnt[i]=(void *)(&fitinputrows[i]); } ffd.nvar=nvar; ffd.wvars=wvars; ffd.functs=lpg.pl_funct; ffd.lf=lf; fiteval=(double *)malloc(sizeof(double)*nrow); for ( i=0 ; if_write; nseparated=get_separate_index(vars,nvar,&idx); /* now we create the internal fit constraint (ifc) matrix & projector: */ ifc.nc=nc+nseparated; ifc.cmatrix=matrix_alloc(nvar); /* explicit constraints are inherited: */ for ( i=0 ; ifconstraint.cmatrix[i][j]; } } /* linear terms imply other constraints which contribute to the projector: */ for ( i=0 ; iparameters.tune.xmmc.skip_initial_fit ) { double **ematrix; double **icmatrix; ematrix=matrix_alloc(nvar); icmatrix=data_get_inversecovariance(fitpnt,fitdep,fitwght,nrow,nvar,bvector,&ffd); get_error_matrix(ematrix,nvar,NULL,icmatrix,ifc.nc,ifc.cproject); matrix_free(icmatrix); find_downhill_simplex_minimum(fitpnt,fitdep,fitwght,nrow,bvector,&ffd,ematrix,nvar,nvar-ifc.nc,idx,nseparated); matrix_free(ematrix); } if ( ! lf->parameters.tune.xmmc.is_adaptive ) rcmatrix=data_get_rootcovariance(fitpnt,fitdep,fitwght,nrow,nvar,bvector,&ffd,ifc.nc,ifc.cproject); else rcmatrix=NULL; /* fprint_matrix(stderr,lf->fconstraint.cproject,nvar,"# "); fprint_matrix(stderr,rcmatrix,nvar,"> "); */ /* if we have constraints, the variables are pushed to the nearest point of the intersections of the hyperplanes defined by the constraints (i.e. the variables are forced to satisfy the constraints with the minimal shift distance). */ if ( nc > 0 ) { for ( i=0 ; i0 ) { constraint_force(bvector,nvar,nc, lf->fconstraint.invlmatrix,lf->fconstraint.cvector); } } chi2=data_get_chisquare_separated_linear(fitpnt,fitdep,fitwght,fiteval,nrow,bvector,&ffd,0,nvar,idx,nseparated,bvector); mchi=chi2; for ( i=0 ; iparameters.tune.xmmc.skip_initial_fit && fw != NULL ) { fprintf(fw,"# Downhill simplex best fit value:\n"); fprintf(fw," "); fwrite_vars_chi2(fw,bvector,vars,nvar,chi2); fflush(fw); } niter=(lf->parameters.tune.xmmc.niter>0?lf->parameters.tune.xmmc.niter:0); for ( iiter=0 ; iiter <= niter ; iiter++ ) { if ( fw != NULL && niter>0 ) { fprintf(fw,"# XMMC: iteration %d:\n",iiter); fflush(fw); } if ( fw != NULL ) { fprintf(fw,"# XMMC values:\n"); fflush(fw); } for ( i=0 ; imc_iterations iterations in a single chain: */ for ( n=0,ccnt=0 ; (lf->parameters.tune.xmmc.count_accepted?ccnt:n)mc_iterations ; n++ ) { /* we assume accaptance, i.e. not out-of-boundary data */ is_not_accepted=0; for ( j=0 ; jparameters.tune.xmmc.is_adaptive ) rcmatrix=data_get_rootcovariance(fitpnt,fitdep,fitwght,nrow,nvar,bvector,&ffd,ifc.nc,ifc.cproject); for ( i=0 ; iparameters.tune.xmmc.is_adaptive ) { matrix_free(rcmatrix); rcmatrix=NULL; } for ( i=0 ; i vars[i].imax ) { is_not_accepted=1; /* o-o-b */ dvector[i]=vars[i].imax; } } for ( i=0 ; idconstraint.ndcfunct && (!is_not_accepted) ; i++ ) { double w; lfit_psn_double_calc(lf->dconstraint.dcfuncts[i].funct,NULL,lpg.pl_funct,&w,dvector); if ( w<=0.0 ) is_not_accepted=1; } /* the next point is not accepted (i.e. it is an out of bound point) */ if ( is_not_accepted ) { /* fprintf(stderr,"qqriq\n"); */ continue; } /* again, constraints are forced to the variables: */ if ( nc > 0 ) { for ( i=0 ; i0 ) { constraint_force(dvector,nvar,nc, lf->fconstraint.invlmatrix,lf->fconstraint.cvector); } } /* we get a new chi square value */ nchi=data_get_chisquare_separated_linear(fitpnt,fitdep,fitwght,fiteval,nrow,dvector,&ffd,0,nvar,idx,nseparated,dvector); /* note: the above call, if nseparated>0 does likely change some elements in dvector[]. */ /* just save it if it is minimal (useful as the fitted values) and */ /* to normalize the chisquare function (i.e. multiply the errors by */ /* some values if desired...) */ if ( nchi0.0 && (u=random_double()) <= alpha ) { for ( i=0 ; i0 ) { corr_sum1[i]/=(double)ccnt; corr_sum2[i]/=(double)ccnt; } s1=corr_sum1[i]; s2=corr_sum2[i]; sig2=s2-s1*s1; if ( sig2<0.0 ) sig2=0.0; for ( n=1 ; n0 && sig2>0.0 ) corr_carr[i][n]=(corr_carr[i][n]-s1*s1*ccnt)/(ccnt*sig2); else corr_carr[i][n]=0.0; } } for ( i=0 ; i0 ; i++ ) { for ( j=0 ; j0 ) { alpha=(double)ccnt/(double)n; dalpha=sqrt((double)ccnt)/(double)n; } else { alpha=0.0; dalpha=0.0; } fprintf(fw,"#\n"); fprintf(fw,"# Accepted transitions / total iterations: %d/%d\n",ccnt,n); fprintf(fw,"# Total acceptance ratio : %.5f +/- %.5f\n",alpha,dalpha); alpha0=xmmc_theoretical_acceptance(nvar-nc-nseparated); fprintf(fw,"# Theoretical probability: %.5f [independent:%d=%d-%d-%d (total-constrained-linear)]\n",alpha0,nvar-nc-nseparated,nvar,nc,nseparated); fprintf(fw,"#\n"); fprintf(fw,"# Correlation lengths: \n"); fprintf(fw,"# "); for ( i=0 ; ifconstraint.nc>0 ) fstr="projected Fisher"; else fstr="Fisher"; fprintf(fw,"# Errors and correlations (%s):\n",fstr); cmatrix=data_get_covariance(fitpnt,fitdep,fitwght,nrow,nvar,mvector,&ffd); for ( i=0 ; i0.0 && tvector[j]>0.0 ) u=cmatrix[i][j]/(tvector[i]*tvector[j]); else u=(i==j?1.0:0.0); fprintf(fw," "); fprintf(fw,lf->corrfm,u); } fprintf(fw,"\n"); } matrix_free(cmatrix); fprintf(fw,"#\n"); fprintf(fw,"# Errors and correlations (statistical, around the best fit):\n"); for ( i=0 ; i0.0 && tvector[j]>0.0 ) u=dcmatrix[i][j]/(tvector[i]*tvector[j]); else u=(i==j?1.0:0.0); fprintf(fw," "); fprintf(fw,lf->corrfm,u); } fprintf(fw,"\n"); } fprintf(fw,"#\n"); } /* this is the main point of the iterative XMMC: we update here */ /* the 'rcmatrix' which generetes the a priori transitions. In the */ /* first (zeroth) iteration, this matrix is derived from the Fisher */ /* infromation matrix, otherwise (later) it is simply the root of */ /* the covariance matrix (which is 'dcmatrix' here): */ if ( iiterparameters.tune.xmmc.is_adaptive ) matrix_free(rcmatrix); if ( fiteval != NULL ) free(fiteval); if ( fitpnt != NULL ) free(fitpnt); if ( fitinputrows != NULL ) { for ( i=0 ; iparameters; nc=lf->fconstraint.nc; /* number of constraints */ nrc=nc; /* number of "real" constraints, i.e. not explicit fixations */ for ( i=0 ; imaxncol)); fitpnt=(void **)malloc(nrow*sizeof(void *)); for ( i=0 ; imaxncol]; fitpnt[i]=(void *)(&fitinputrows[i]); } ffd.nvar=nvar; ffd.wvars=wvars; ffd.functs=lpg.pl_funct; ffd.lf=lf; for ( i=0 ; if_write; data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,bvector,&ffd,1); data_get_scatters(fitpnt,fitdep,fitwght,NULL,nrow,bvector,&ffd,0); if ( fw != NULL ) { fprintf(fw,"#"); fprint_variable_name_list(fw,vars,nvar); fprint_derived_variable_name_list(fw,dvars,ndvar); fprintf(fw,"\n"); fprintf(fw,"#"); fprint_variable_name_index(fw,vars,nvar); fprint_derived_variable_name_index(fw,dvars,ndvar,nvar); fprintf(fw,"\n"); } if ( fw != NULL && fp->tune.fima.write_original ) { fprintf(fw,"# Fisher analysis - original data:\n"); if ( fp->tune.fima.do_montecarlo ) fprintf(fw,"# "); else fprintf(fw," "); fwrite_vars(fw,bvector,vars,nvar); fwrite_dvars(fw,bvector+nvar,dvars,ndvar); fprintf(fw,"\n"); fprintf(fw,"# Scatters (RMS, reduced \\chi^2): \n"); for ( i=0 ; indatablock ; i++ ) { fprintf(fw,"# [%s] %12g %12.8f\n", lf->datablocks[i].key, lf->datablocks[i].dbscatter, lf->datablocks[i].dbredchi2); } fflush(fw); } rcmatrix=data_get_rootcovariance(fitpnt,fitdep,fitwght,nrow,nvar,bvector,&ffd,lf->fconstraint.nc,lf->fconstraint.cproject); for ( n=0 ; nmc_iterations && fp->tune.fima.do_montecarlo ; n++ ) { for ( j=0 ; j 0 ) { for ( i=0 ; i0 ) { constraint_force(dvector,nvar,nc, lf->fconstraint.invlmatrix,lf->fconstraint.cvector); } } if ( fw != NULL ) { chi2=data_get_chisquare(fitpnt,fitdep,fitwght,NULL,nrow,dvector,&ffd,1); fwrite_vars_chi2(fw,dvector,vars,nvar,chi2); } } matrix_free(rcmatrix); if ( fw != NULL ) { char *fstr; double **cmatrix,**ocmatrix,*tvector; double u; if ( lf->fconstraint.nc>0 ) fstr="projected Fisher"; else fstr="Fisher"; if ( fp->tune.fima.write_uncert ) fprintf(fw,"# Uncertainties (%s):\n",fstr); tvector=vector_alloc(nvar+ndvar); cmatrix=matrix_alloc(nvar+ndvar); ocmatrix=data_get_covariance(fitpnt,fitdep,fitwght,nrow,nvar,bvector,&ffd); if ( ocmatrix != NULL ) { int k,l,m,n; double c,p1,p2,**diff; diff=matrix_alloc(nvar+ndvar); for ( k=0 ; ktune.fima.do_montecarlo ) fprintf(fw,"# "); else fprintf(fw," "); if ( fp->tune.fima.write_uncert ) { fwrite_vars(fw,tvector,vars,nvar);fprintf(fw,"\n"); } } else { for ( i=0 ; itune.fima.write_uncert ) { if ( fp->tune.fima.do_montecarlo ) fprintf(fw,"# "); else fprintf(fw," "); fwrite_vars(fw,tvector,vars,nvar); fwrite_dvars(fw,tvector+nvar,dvars,ndvar); fprintf(fw,"\n"); } if ( fp->tune.fima.write_correl ) { fprintf(fw,"# Correlations:\n"); for ( i=0 ; itune.fima.do_montecarlo ) fprintf(fw,"# "); for ( j=0 ; j0.0 && tvector[j]>0.0 ) u=cmatrix[i][j]/(tvector[i]*tvector[j]); else u=(i==j?1.0:0.0); fprintf(fw," "); fprintf(fw,lf->corrfm,u); } fprintf(fw,"\n"); } } matrix_free(cmatrix); } vector_free(tvector); } if ( fitpnt != NULL ) free(fitpnt); if ( fitinputrows != NULL ) { for ( i=0 ; ifconstraint.nc; /* number of constraints */ nrc=nc; /* number of "real" constraints, i.e. not explicit fixations */ for ( i=0 ; imaxncol)); fitpnt=(void **)malloc(nrow*sizeof(void *)); for ( i=0 ; imaxncol]; fitpnt[i]=(void *)(&fitinputrows[i]); } ffd.nvar=nvar; ffd.wvars=wvars; ffd.functs=lpg.pl_funct; ffd.lf=lf; for ( i=0 ; ifconstraint.cmatrix[i][j]; } } /* linear terms imply other constraints which contribute to the projector: */ for ( i=0 ; ifconstraint.nc,lf->fconstraint.cproject); /* the simplex dimension in the hyperplane is nvar-nc-nseparated, i.e. */ /* both the explicit constraints and the implied ones (by the linear */ /* separation) decrease the dimension of the embeddning hyperplane: */ chi2=find_downhill_simplex_minimum(fitpnt,fitdep,fitwght,nrow,bvector,&ffd,ematrix,nvar,nvar-nc-nseparated,NULL,0); fw=off->f_write; if ( fw != NULL ) { fprintf(fw,"# Downhill simplex best fit values:\n"); fwrite_vars_chi2(fw,bvector,vars,nvar,chi2); } if ( idx != NULL ) free(idx); matrix_free(ematrix); vector_free(evector); vector_free(bvector); return(0); } /*****************************************************************************/ int evaluate_and_dump(FILE *fr,FILE *fw,datablock *db, variable *vars,int nvar,int *colouts,int ncolout, dumpexpr *exprs,int nexpr) { int i,j,ln,len,is_cont,nt,mxcolout; double *wvars,*lvars,*frets; char *rbuff,**lvarstr; int cnc; if ( db->funct != NULL ) nt=db->funct->nseq; else nt=1; frets=(double *)malloc(sizeof(double)*nt); wvars=(double *)malloc(sizeof(double)*(nvar+db->ncol)); lvars=(double *)malloc(sizeof(double)*(nvar+db->ncol)); ln=0; mxcolout=0; if ( colouts != NULL && ncolout>0 ) { for ( i=0 ; imxcolout ) mxcolout=colouts[i]; } mxcolout++; } rbuff=NULL;lvarstr=NULL; while ( ! feof(fr) ) { ln++; if ( rbuff != NULL ) { free(rbuff); rbuff=NULL; } if ( lvarstr != NULL ) { free(lvarstr);lvarstr=NULL; } rbuff=freadline(fr); if ( rbuff==NULL ) break; len=strlen(rbuff); for ( i=0 ; incol ) { if ( is_verbose>=0 ) fprint_warning("missing column in line %d, skipped",ln); continue; } is_cont=0; for ( i=0 ; incol && (!is_cont) ; i++ ) { if ( db->cols[i].name != NULL && db->cols[i].name[0] ) { j=sscanf(lvarstr[i],"%lg",&lvars[i]); if ( j<1 || (! isfinite(lvars[i])) ) { if ( is_verbose>=0 ) fprint_warning("inappropriate field '%s' in line %d, skipped",lvarstr[i],ln); is_cont=1; } } else lvars[i]=0.0; } if ( is_cont ) continue; if ( db->funct != NULL ) { for ( i=0 ; incol ; i++ ) { wvars[i+nvar]=lvars[i]; } lfit_psn_double_calc(db->funct,db->fchain,lpg.pl_funct,frets,wvars); } else if ( db->lfunct != NULL ) { for ( i=0 ; ilfunct->nvar ; i++ ) { wvars[i]=vars[db->map_var[i]].init; } for ( i=0 ; ilfunct->nidv ; i++ ) { wvars[i+nvar]=lvars[db->map_idv[i]]; } db->lfunct->function(wvars,wvars+nvar,frets,NULL); } if ( colouts != NULL && ncolout>0 ) { for ( i=0 ; iname=varstr; wv->flags=0; wv->diff=0.0; wv->is_linear=0; wv->is_separated=0; strcpy(wv->format,LFIT_DEFAULT_FORMAT); while ( *varstr && *varstr != '=' && *varstr != ',' ) varstr++; if ( *varstr=='=' ) { if ( varstr != varstr0 && *(varstr-1)==':' ) { wv->flags |= VAR_IS_CONSTANT; *(varstr-1)=0; } *varstr=0,varstr++; if ( sscanf(varstr,"[%lg:%lg:%lg]",&imin,&istp,&imax)==3 ) { wv->init=0.0 ,wv->ierr=0.0; if ( istp<0.0 ) istp=-istp; if ( imin>imax ) w=imin,imin=imax,imax=w; wv->imin=imin,wv->imax=imax; wv->istp=istp; wv->flags |= (VAR_MIN|VAR_STEP|VAR_MAX); } else if ( sscanf(varstr,"%lg:%lg[%lg:%lg]",&init,&ierr,&imin,&imax)==4 ) { wv->init=init,wv->ierr=ierr; if ( imin>imax ) w=imin,imin=imax,imax=w; wv->imin=imin,wv->imax=imax; wv->flags |= (VAR_MIN|VAR_MAX|VAR_ERR); } else if ( sscanf(varstr,"%lg[%lg:%lg]%lg",&init,&imin,&imax,&ierr)==4 ) { wv->init=init,wv->ierr=ierr; if ( imin>imax ) w=imin,imin=imax,imax=w; wv->imin=imin,wv->imax=imax; wv->flags |= (VAR_MIN|VAR_MAX|VAR_ERR); } else if ( sscanf(varstr,"%lg:%lg[:%lg]",&init,&ierr,&imax)==3 ) { wv->init=init,wv->ierr=ierr; wv->imin=0.0 ,wv->imax=imax; wv->flags |= (VAR_MAX|VAR_ERR); } else if ( sscanf(varstr,"%lg:%lg[%lg:]",&init,&ierr,&imin)==3 ) { wv->init=init,wv->ierr=ierr; wv->imin=imin,wv->imax=0.0 ; wv->flags |= (VAR_MIN|VAR_ERR); } else if ( sscanf(varstr,"%lg[:%lg]:%lg",&init,&imax,&ierr)==3 ) { wv->init=init,wv->ierr=ierr; wv->imin=0.0 ,wv->imax=imax; wv->flags |= (VAR_MAX|VAR_ERR); } else if ( sscanf(varstr,"%lg[%lg:]:%lg",&init,&imin,&ierr)==3 ) { wv->init=init,wv->ierr=ierr; wv->imin=imin,wv->imax=0.0 ; wv->flags |= (VAR_MIN|VAR_ERR); } else if ( sscanf(varstr,"%lg[%lg:%lg]",&init,&imin,&imax)==3 ) { wv->init=init,wv->ierr=1.0; if ( imin>imax ) w=imin,imin=imax,imax=w; wv->imin=imin,wv->imax=imax; wv->flags |= (VAR_MIN|VAR_MAX); } else if ( sscanf(varstr,"%lg[:%lg]",&init,&imax)==2 ) { wv->init=init,wv->ierr=1.0; wv->imin=0.0 ,wv->imax=imax; wv->flags |= (VAR_MAX); } else if ( sscanf(varstr,"%lg[%lg:]",&init,&imin)==2 ) { wv->init=init,wv->ierr=1.0; wv->imin=imin,wv->imax=0.0; wv->flags |= (VAR_MIN); } else if ( sscanf(varstr,"%lg:%lg",&init,&ierr)==2 ) { wv->init=init,wv->ierr=ierr; wv->flags |= (VAR_ERR); } else if ( sscanf(varstr,"%lg",&init)==1 ) wv->init=init,wv->ierr=1.0; else wv->init=0.0, wv->ierr=1.0; /* r1=sscanf(varstr,"%lg[%lg]",&wv->init,&wv->ierr); r2=sscanf(varstr,"%lg:%lg" ,&wv->init,&wv->ierr); r=(r1>r2?r1:r2); if ( r<1 ) { wv->init=0.0; wv->ierr=1.0; } else if ( r<2 ) wv->ierr=1.0; */ /* obsolete (simpler) format parser */ } else { wv->init=0.0; wv->ierr=0.0; /* unused */ wv->imin=wv->imax=0.0; /* unused */ wv->flags=0; } while ( *varstr && *varstr != ',' ) varstr++; if ( *varstr==',' ) *varstr=0,varstr++; nvar++; } if ( rvars != NULL ) *rvars=vars; if ( rnvar != NULL ) *rnvar=nvar; return(0); } int extract_derived_variables(char *dvrstr,dvariable **rdvars,int *rndvar) { dvariable *dvars,*wv; int ndvar,pl; char *dvrstr0; dvars=NULL; ndvar=0; while ( *dvrstr ) { dvars=(dvariable *)realloc(dvars,sizeof(dvariable)*(ndvar+1)); wv=&dvars[ndvar]; wv->name=dvrstr; strcpy(wv->format,LFIT_DEFAULT_FORMAT); while ( *dvrstr && *dvrstr != '=' && *dvrstr != ',' ) dvrstr++; if ( *dvrstr != '=' ) { free(dvars); dvars=NULL; return(1); } *dvrstr=0,dvrstr++; dvrstr0=dvrstr; pl=0; while ( *dvrstr ) { if ( *dvrstr=='(' ) pl++; else if ( *dvrstr==')' ) pl--; else if ( *dvrstr==',' && pl<=0 ) break; dvrstr++; } wv->expr=dvrstr0; if ( *dvrstr==',' ) *dvrstr=0,dvrstr++; /* fprintf(stderr,"[%s]=[%s]\n",wv->name,wv->expr); */ ndvar++; } if ( rdvars != NULL ) *rdvars=dvars; if ( rndvar != NULL ) *rndvar=ndvar; return(0); } int format_check(char *f) { while ( *f=='-' || *f=='+' ) f++; while ( isdigit((int)*f) ) f++; if ( *f=='+' ) f++; if ( *f=='.' ) f++; if ( *f=='+' ) f++; while ( isdigit((int)*f) ) f++; if ( *f=='e' || *f=='E' || *f=='f' || *f=='F' || *f=='g' || *f=='G' ) return(0); else return(1); } int extract_variable_formats(char *formatstr, variable *vars,int nvar,dvariable *dvars,int ndvar) { char *fstr,**formats,*args[4],*p; int i,k0,k1,n,is_failed; if ( formatstr==NULL ) return(0); fstr=strdup(formatstr); remove_spaces(fstr); is_failed=0; formats=tokenize_char_dyn(fstr,','); for ( i=0 ; formats != NULL && formats[i] != NULL && ! is_failed ; i++ ) { for ( p=formats[i] ; *p ; p++ ) { if ( *p==':' ) *p='='; } n=tokenize_char(formats[i],args,'=',2); if ( n<2 ) { is_failed=1; break; } for ( k0=0 ; vars != NULL && k0=nvar ; k1++ ) { if ( strcmp(dvars[k1].name,args[0])==0 ) break; } if ( k0>=nvar && k1>=ndvar ) { is_failed=1; break; } p=args[1]; while ( *p=='%' ) p++; if ( strlen(p)>14 || format_check(p) ) { is_failed=1; break; } if ( k0=nvar ) { is_failed=1; break; } if ( sscanf(args[1],"%lg",&diff)<1 ) { is_failed=1; break; } vars[k].diff=diff;; } if ( diffs != NULL ) free(diffs); free(vstr); return(is_failed); } int extract_dumpexpr_formats(char *formatstr,dumpexpr **rexprs,int *rnexpr) { dumpexpr *exprs; int nexpr; char *fstr,**formats,*p; int i,is_failed; if ( formatstr==NULL ) { *rexprs=NULL; *rnexpr=0; return(0); } exprs=NULL; nexpr=0; fstr=strdup(formatstr); remove_spaces(fstr); is_failed=0; formats=tokenize_char_dyn(fstr,','); for ( i=0 ; formats != NULL && formats[i] != NULL && ! is_failed ; i++ ) { p=formats[i]; while ( *p=='%' ) p++; if ( strlen(p)>14 || format_check(p) ) { is_failed=1; break; } exprs=realloc(exprs,sizeof(dumpexpr)*(nexpr+1)); exprs[nexpr].format[0]='%'; strcpy(exprs[nexpr].format+1,p); nexpr++; } if ( formats != NULL ) free(formats); free(fstr); if ( is_failed ) { if ( exprs != NULL ) free(exprs); exprs=NULL; nexpr=0; } *rexprs=exprs; *rnexpr=nexpr; return(is_failed); } int extract_columns(char *colstr,column **rcols,int *rncol) { column *cols,*wc; int ncol,cc,pc; /* num of columns, current col., previous col. */ int i; char *name; cols=NULL; ncol=0; if ( rcols != NULL ) *rcols=cols; if ( rncol != NULL ) *rncol=ncol; pc=-1; while ( *colstr ) { name=colstr; while ( *colstr && *colstr != ',' && *colstr != ':' ) colstr++; if ( *colstr==':' ) { *colstr=0,colstr++; sscanf(colstr,"%d",&cc); cc--; } else if ( pc<0 ) cc=0; else cc=pc+1; /* invalid */ if ( cc<0 ) { if ( cols != NULL ) free(cols); return(1); } /* new */ if ( cc>=ncol ) { int pcol; pcol=ncol; ncol=cc+1; cols=(column *)realloc(cols,sizeof(cols)*ncol); for ( i=pcol ; iname=name; while ( *colstr && *colstr != ',' ) colstr++; if ( *colstr==',' ) *colstr=0,colstr++; pc=cc; }; for ( i=0 ; interm ; j++ ) { if ( w->terms[j].type==T_VAR && w->terms[j].major < nvar ) return(1); } return(0); } int build_psn_replace_macros(psn **rfunct) { psnmacro *wmacro; psn *funct; if ( lpg.pl_macro==NULL ) return(0); for ( wmacro=lpg.pl_macro ; wmacro->name != NULL ; wmacro++ ) { funct=psn_replace(*rfunct,wmacro->major,wmacro->pmacro,NULL); psn_free(*rfunct); *rfunct=funct; } return(0); } static int build_psn_search_symbol(psnsym **mysyms,char *name) { psnsym *ws; for ( ; *mysyms != NULL ; mysyms++ ) { for ( ws=*mysyms ; ws->type && ws->name != NULL ; ws++ ) { if ( ws->type==T_VAR && strcmp(ws->name,name)==0 ) { return(ws->major); } } } return(-1); } int build_psn_base_sequences(datablock *db,char *fncstr, lfitfunction *lfuncts,int nlfunct, psnsym **mysyms,int nvar) { if ( fncstr==NULL || db==NULL || mysyms==NULL ) return(-1); else if ( fncstr[0]=='@' ) { char *lstr,*p,**arr; int i,l,n,m; lfitfunction *ll; fncstr++; lstr=strdup(fncstr); remove_spaces(lstr); l=strlen(lstr); p=strchr(lstr,'('); if ( p==NULL || l<1 || lstr[l-1] != ')' ) { free(lstr); return(7); } lstr[l-1]=0; *p=0; p++; for ( i=0,ll=NULL ; invar + ll->nidv) ) { if ( arr != NULL ) free(arr); free(lstr); return(7); } db->lfunct =ll; db->map_var=(int *)malloc(sizeof(int)*ll->nvar); db->map_idv=(int *)malloc(sizeof(int)*ll->nidv); for ( i=0 ; invar && m>=nvar) ) { free(arr); free(lstr); return(7); } if ( invar ) db->map_var[i]=m; else db->map_idv[i-ll->nvar]=m-nvar; } if ( arr != NULL ) free(arr); free(lstr); db->funct=NULL; db->functorig=NULL; db->diff=NULL; } else { psn *w,*pfunct; w=psn_conv_string(fncstr,mysyms); if ( w==NULL ) return(7); if ( psn_init(w,lpg.pl_prop) ) return(8); pfunct=psn_conv(w,lpg.pl_prop); if ( pfunct==NULL ) return(8); if ( psn_test(pfunct) ) return(8); psn_free(w); build_psn_replace_macros(&pfunct); db->funct=pfunct; psn_optimize(db->funct); db->fchain=psn_argument_chain(db->funct); lfit_psn_chain_optimize(db->funct,db->fchain); db->functorig=pfunct; db->lfunct =NULL; db->map_var=NULL; db->map_idv=NULL; } db->diff =NULL; db->dep =NULL; db->err =NULL; db->is_linear=0; return(0); } int lfitfunction_is_differentiable(lfitfunction *ll) { if ( ll->flags==LFITFUNCTION_DIFFERENTIABLE ) return(1); else if ( ll->flags==LFITFUNCTION_LINEAR ) return(1); else return(0); } int lfitfunction_is_linear(lfitfunction *ll) { if ( ll->flags==LFITFUNCTION_LINEAR ) return(1); else return(0); } int build_psn_fit_sequences(datablock *db,char *fncstr,char *depstr, lfitfunction *lfuncts,int nlfunct, char *errstr,psnsym **mysyms, variable *vars,int nvar,int force_nonlin,int calc_derivatives) { psn *w,*pfunctorig,*pfunct,**pdiff,*pdep,*perr,*psub; int is_linear,i,j,is_fitvar_fnc,is_fitvar_dep; if ( fncstr==NULL || db==NULL || mysyms==NULL ) return(-1); /* be optimistic: */ for ( i=0 ; invar + ll->nidv) ) { if ( arr != NULL ) free(arr); free(lstr); return(7); } db->lfunct =ll; db->map_var=(int *)malloc(sizeof(int)*ll->nvar); db->map_idv=(int *)malloc(sizeof(int)*ll->nidv); db->is_linear=lfitfunction_is_linear(ll); for ( i=0 ; invar && m>=nvar) ) { free(arr); free(lstr); return(7); } if ( invar ) { db->map_var[i]=m; if ( ! db->is_linear ) vars[m].is_linear=0; /* excluded */ } else db->map_idv[i-ll->nvar]=m-nvar; } if ( arr != NULL ) free(arr); free(lstr); w=psn_conv_string(depstr,mysyms); if ( w==NULL ) return(12); if ( psn_init(w,lpg.pl_prop) ) return(13); pdep=psn_conv(w,lpg.pl_prop); if ( pdep==NULL ) return(13); if ( psn_test(pdep) ) return(13); psn_free(w); db->dep =pdep; db->funct=NULL; db->functorig=NULL; db->diff=NULL; } else { w=psn_conv_string(fncstr,mysyms); if ( w==NULL ) return(7); if ( psn_init(w,lpg.pl_prop) ) return(8); pfunct=psn_conv(w,lpg.pl_prop); if ( pfunct==NULL ) return(8); if ( psn_test(pfunct) ) return(8); psn_free(w); build_psn_replace_macros(&pfunct); w=psn_conv_string(depstr,mysyms); if ( w==NULL ) return(12); if ( psn_init(w,lpg.pl_prop) ) return(13); pdep=psn_conv(w,lpg.pl_prop); if ( pdep==NULL ) return(13); if ( psn_test(pdep) ) return(13); psn_free(w); build_psn_replace_macros(&pdep); is_fitvar_fnc=is_var_in_psn(pfunct,nvar); is_fitvar_dep=is_var_in_psn(pdep,nvar); if ( ! is_fitvar_fnc && ! is_fitvar_dep ) return(23); else if ( is_fitvar_fnc && is_fitvar_dep ) return(24); else if ( is_fitvar_dep && ! is_fitvar_fnc ) w=pfunct,pfunct=pdep,pdep=w; pfunctorig=psn_duplicate(pfunct); is_linear=1; pdiff=(psn **)malloc(sizeof(psn *)*nvar); for ( i=0 ; interm ; j++ ) { if ( psub->terms[j].type==T_VAR && psub->terms[j].major < nvar ) { psub->terms[j].type=T_SCONST; psub->terms[j].major=0; } } j=psn_simplify(psub,lpg.pl_simp,lpg.pl_prop,lpg.pl_funct); if ( psub->nterm>1 ) is_linear=0; else if ( ! ( psub->terms[0].type==T_SCONST && psub->terms[0].major==0 ) ) is_linear=0; if ( ! is_linear ) { if ( is_verbose>=0 ) fprint_warning("fit function is nonlinear but affine, it is going to be re-ordered"); psn_concate(pfunct,psub); psn_append_term(pfunct,T_OP,O_SUB,2,-1); pfunct->nseq--; is_linear=1; for ( i=0 ; inseq--; } db->funct =pfunct; psn_optimize(db->funct); db->fchain=psn_argument_chain(db->funct); lfit_psn_chain_optimize(db->funct,db->fchain); db->diff =pdiff; db->dep =pdep; db->functorig=pfunctorig; db->is_linear=is_linear; } if ( errstr != NULL ) { w=psn_conv_string(errstr,mysyms); if ( w==NULL ) return(12); if ( psn_init(w,lpg.pl_prop) ) return(12); perr=psn_conv(w,lpg.pl_prop); if ( perr==NULL ) return(12); if ( psn_test(perr) ) return(12); psn_free(w); build_psn_replace_macros(&perr); } else perr=NULL; db->err =perr; return(0); } int build_psn_constraint_sequences(lfitdata *lf,char *cntstr,psnsym **mysyms, variable *vars,int nvar) { psn *w,*pcnt,*pcdf; int i,j; fitconstraint *fc; domconstraint *dc; /* process the constraint argument after -t|--constraint . */ /* this is a comma-separated list of = */ /* terms where is an arbitrary linear expression where all */ /* symbolic variables are the name of variables to be fitted. */ fc=&lf->fconstraint; dc=&lf->dconstraint; if ( cntstr != NULL ) { char *c,*cstr,**ctokens; int nn,nc,l,ctype; double **cmatrix,*cvector,*wvector; cmatrix=matrix_alloc(nvar); cvector=vector_alloc(nvar); wvector=vector_alloc(nvar); for ( j=0 ; jndcfunct=0; dc->dcfuncts=NULL; cstr=strdup(cntstr); for ( c=cstr,l=0 ; *c ; c++ ) { if ( *c=='(' || *c=='[' || *c=='{' ) l++; else if ( *c==')' || *c==']' || *c=='}' ) l--; else if ( *c==',' && l <= 0 ) *c=';'; } ctokens=tokenize_char_dyn(cstr,';'); for ( nn=0 ; ctokens[nn] != NULL ; nn++ ) { char *p1,*p2,*cstr; remove_spaces(ctokens[nn]); p1=ctokens[nn]; p2=NULL; ctype=0; for ( c=p1 ; *c ; c++ ) { if ( *c=='<' && *(c+1)=='=' ) ctype=-1,p2=c+2; else if ( *c=='=' && *(c+1)=='<' ) ctype=-1,p2=c+2; else if ( *c=='>' && *(c+1)=='=' ) ctype=+1,p2=c+2; else if ( *c=='=' && *(c+1)=='>' ) ctype=+1,p2=c+2; else if ( *c=='=' && *(c+1)=='=' ) ctype=0,p2=c+2; else if ( *c=='<' ) ctype=-2,p2=c+1; else if ( *c=='>' ) ctype=+2,p2=c+1; else if ( *c=='=' ) ctype=0,p2=c+1; if ( p2 != NULL ) break; } cstr=NULL; if ( p2 != NULL ) { *c=0; if ( ctype<0 ) { strappendf(&cstr,"(%s)-(%s)",p2,p1); ctype=-ctype; } else strappendf(&cstr,"(%s)-(%s)",p1,p2); } else strappendf(&cstr,"(%s)",p1); /* fprintf(stderr,"cstr='%s'\n",cstr); */ w=psn_conv_string(cstr,mysyms); free(cstr); if ( w==NULL ) return(19); if ( psn_init(w,lpg.pl_prop) ) return(19); pcnt=psn_conv(w,lpg.pl_prop); if ( pcnt==NULL ) return(19); if ( psn_test(pcnt) ) return(19); psn_free(w); build_psn_replace_macros(&pcnt); /* check if there's any non-fitting variable in the expression */ w=pcnt; for ( j=0 ; jnterm ; j++ ) { if ( w->terms[j].type==T_VAR && w->terms[j].major>=nvar ) break; } /* if yes, break. */ if ( w->nterm && jnterm ) return(19); /* domain constraint: */ if ( ctype ) { dcfunct *dcf; dc->dcfuncts=(dcfunct *)realloc(dc->dcfuncts,sizeof(dcfunct)*(dc->ndcfunct+1)); dcf=&dc->dcfuncts[dc->ndcfunct]; dcf->funct=pcnt; dcf->ctype=ctype; dc->ndcfunct++; } /* fit constraint: too many: */ else if ( nc>=nvar ) return(21); /* fit constraint: */ else { int i,j; double cleft; cleft=0.0; for ( i=0 ; interm ; j++ ) { if ( w->terms[j].type==T_VAR ) break; } /* if yes, then the constraint is non-linear, break */ if ( w->nterm && jnterm ) return(19); /* calculate the derivative */ lfit_psn_double_calc(pcdf,NULL,lpg.pl_funct,&cmatrix[nc][i],wvector); psn_free(pcdf); } lfit_psn_double_calc(pcnt,NULL,lpg.pl_funct,&cleft,wvector); cvector[nc]=-cleft; psn_free(pcnt); nc++; } } free(ctokens); free(cstr); vector_free(wvector); fc->nc=nc; fc->cmatrix =cmatrix; fc->cvector =cvector; } else { fc->nc=0; fc->cmatrix =NULL; fc->cvector =NULL; dc->ndcfunct=0; dc->dcfuncts=NULL; } /* add extra constraints, if the given variable (to be fitted) was declared */ /* as := instead of =. */ for ( i=0 ; inc >= nvar ) return(21); if ( fc->cmatrix==NULL ) fc->cmatrix=matrix_alloc(nvar); if ( fc->cvector==NULL ) fc->cvector=vector_alloc(nvar); for ( j=0 ; jcmatrix[fc->nc][j]=(i==j?1.0:0.0); } fc->cvector[fc->nc]=vars[i].init; fc->nc++; } if ( fc->nc > 0 ) { double **invlmatrix; double **cproject; invlmatrix=matrix_alloc(nvar+fc->nc); cproject =matrix_alloc(nvar); if ( constraint_initialize_lambda_matrix(fc->nc,nvar,fc->cmatrix,invlmatrix) ) return(19); constraint_initialize_proj_matrix(fc->nc,nvar,fc->cmatrix,cproject); fc->cproject =cproject; fc->invlmatrix=invlmatrix; } else { double **invlmatrix; double **cproject; cproject =matrix_alloc(nvar); invlmatrix=matrix_alloc(nvar); for ( i=0 ; iinvlmatrix=invlmatrix; fc->cproject =cproject; } return(0); } int build_psn_derived_variable_expression(dvariable *wv,psnsym **mysyms,int nvar,int is_calc_derivatives) { psn *w,*pfunct; int i; if ( wv->expr==NULL ) return(-1); w=psn_conv_string(wv->expr,mysyms); if ( w==NULL ) return(1); if ( psn_init(w,lpg.pl_prop) ) return(2); pfunct=psn_conv(w,lpg.pl_prop); if ( pfunct==NULL ) return(2); if ( psn_test(pfunct) ) return(2); psn_free(w); build_psn_replace_macros(&pfunct); wv->funct=pfunct; if ( is_calc_derivatives ) { wv->diff=(psn **)malloc(sizeof(psn *)*nvar); for ( i=0 ; idiff[i]=psn_diff_simplify(wv->funct,lpg.pl_prop,lpg.pl_diff,lpg.pl_simp,lpg.pl_funct,i); if ( wv->diff[i]==NULL ) return(3); } } else wv->diff=NULL; return(0); } /*****************************************************************************/ #define F_RANDOM 124 /* random(): uniform [0:1] */ #define F_GAUSSIAN 125 /* gaussian(): normal dist */ static int funct_f_random(double *s) { *s=random_double(); return(0); } static int funct_f_gaussian(double *s) { *s=get_gaussian(0.0,1.0); return(0); } int lfit_register_random_functions(void) { int r; r=0; r|=lfit_register_function("random" , F_RANDOM ,0,funct_f_random ,NULL,"random()" ); r|=lfit_register_function("gaussian", F_GAUSSIAN,0,funct_f_gaussian,NULL,"gaussian()"); return(0); } int lfit_define_single_macro(lfitdata *lf,int major,char *macro,char **ereason) { int i,argnum,nmacro; psnsym *argsyms; char *name,*firstarg,**args; psnsym *mysyms[8]; psn *w,*pmacro; psnmacro *wmacro; remove_spaces_and_comments(macro); name=macro; while ( *macro && *macro != '(' ) macro++; if ( ! *macro ) { if ( ereason != NULL ) *ereason="empty macro definition(?)"; return(1); } *macro=0,macro++; if ( lfit_register_symbol_exists(&lpg,name) ) { if ( ereason != NULL ) *ereason="macro name is used by a built-in function or by a previously defined macro"; return(2); } else if ( lfit_check_symbol_name(name) ) { if ( ereason != NULL ) *ereason="macro name contains unexpected character(s)"; return(2); } firstarg=macro; while ( *macro && *macro != ')' ) macro++; if ( ! *macro ) { if ( ereason != NULL ) *ereason="unexpected format/syntax for macro definition"; return(3); } *macro=0,macro++; if ( *macro != '=' ) { if ( ereason != NULL ) *ereason="unexpected format/syntax for macro definition"; return(4); } macro++; args=tokenize_char_dyn(firstarg,','); for ( argnum=0 ; args[argnum] != NULL ; ) argnum++; if ( args==NULL || argnum<1 ) { if ( args != NULL ) free(args); if ( ereason != NULL ) *ereason="macro should have at least one argument"; return(5); } argsyms=(psnsym *)malloc(sizeof(psnsym)*(argnum+1)); for ( i=0 ; iname=strdup(name); wmacro->pmacro=pmacro; wmacro->major=major; wmacro->argnum=argnum; /* fprintf(stderr,"lfit_register_function(): name=%s major=%d argnum=%d\n",wmacro->name,wmacro->major,argnum); */ if ( lfit_register_function(wmacro->name,wmacro->major,argnum,NULL,NULL,NULL) ) { if ( ereason != NULL ) *ereason="registration failed"; return(9); } nmacro++; wmacro=&lpg.pl_macro[nmacro]; wmacro->name=NULL; wmacro->pmacro=NULL; wmacro->major=0; wmacro->argnum=0; return(0); } int lfit_define_macro(lfitdata *lf,char *imacro,int *omajor) { char *macro,*c,**macrolist,**m,*reason; int plevel,ret; if ( imacro==NULL ) return(0); macro=strdup(imacro); for ( c=macro,plevel=0 ; *c ; c++ ) { if ( *c == '(' ) plevel++; else if ( *c == ')' ) plevel--; else if ( *c == ',' && plevel <= 0 ) *c=';'; } macrolist=tokenize_char_dyn(macro,';'); ret=0; for ( m=macrolist ; macrolist != NULL && *m != NULL ; m++ ) { ret=lfit_define_single_macro(lf,*omajor,*m,&reason); if ( ret ) { fprint_warning("unable to register macro '%s': %s",*m,reason); } (*omajor)++; } if ( macrolist != NULL ) free(macrolist); free(macro); return(ret); } /*****************************************************************************/ int lfit_is_method_requries_derivatives(int fit_method) { int ret; switch ( fit_method ) { case FIT_METHOD_CLLS: case FIT_METHOD_NLLM: case FIT_METHOD_XMMC: case FIT_METHOD_FIMA: ret=1; break; case FIT_METHOD_MCMC: case FIT_METHOD_MCHI: case FIT_METHOD_EMCE: case FIT_METHOD_DHSX: case FIT_METHOD_LMND: ret=0; break; case FIT_METHOD_NONE: ret=0; break; default: /* unexpected */ ret=0; break; } return(ret); } int lfit_is_method_random(int fit_method) { int ret; switch ( fit_method ) { case FIT_METHOD_MCMC: case FIT_METHOD_EMCE: case FIT_METHOD_XMMC: case FIT_METHOD_FIMA: ret=1; break; default: ret=0; break; } return(ret); } int lfit_set_separated_linears(fitconstraint *fc,variable *vars,int nvar,char *varseplist) { char *list,**cmd,*p; int c,i,n,set; if ( varseplist==NULL || (*varseplist)==0 ) return(0); list=strdup(varseplist); cmd=tokenize_char_dyn(varseplist,','); if ( cmd==NULL ) { free(list); return(0); } for ( n=0 ; cmd[n] != NULL ; n++ ) { p=cmd[n]; if ( strcmp(p,"@")==0 ) { for ( i=0 ; i=0 ) fprint_warning("(one of the) fit function(s) is nonlinear in the parametric variable '%s', separation ignored",vars[i].name); else if ( i>=nvar ) return(1); } } free(cmd); free(list); /* This loop below guarantees that the set of parametric variables affacted by explicit constraints and the set of variables separated (because of their lineary) are completely disjoint. That would be a great fun both for its theoretical aspects and for implementation, to see what's going on if these sets are not disjoint. However, in practice this occurs barely, eventually, coupled constraints (this is the main point) are used when the model function is linear in these parametric variables. */ for ( c=0 ; cnc && fc->cmatrix != NULL ; c++ ) { for ( i=0 ; icmatrix[c][i] != 0.0 && vars[i].is_separated ) { /* tbd: print some warning here? */ vars[i].is_separated=0; } } } return(0); } /*****************************************************************************/ int f_lfitfunction_generic(double *stack) { return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { FILE *fr,*fw; char *ofname,*oaname,*obname,*outname, *inname,*oxname,*ovname; int i,errdump,resdump,is_help,is_warn_obsolete,is_dump_delta,seed; int is_fit,force_nonlin, is_weighted_sigma,*colouts,ncolout; fitout of; char *fncstr,*depstr,*errstr,*colstr, *varstr,*dvrstr, *cntstr,*clostr, *vardiffstr,*formatstr,*corrfmstr,*varseplist, **xdefinelist,*perturbstr,*submethodstr; char **inp_keys,**inp_args, **col_keys,**col_args, **fnc_keys,**fnc_args, **dep_keys,**dep_args, **err_keys,**err_args, **wgt_keys,**wgt_args; char **keys; int nkey; int errtype; /* errtype=0: sigma, errtype=1: weight */ variable *vars; /* primary variables to fit / to analyze */ int nvar; dvariable *dvars; /* derived variables of the analysis */ int ndvar; dumpexpr *exprs; int nexpr; char **dliblist; /* user argument */ lfitdynlib *ldyns; /* dynamically loaded stuff */ int nldyn; lfitfunction *lfuncts; /* gathered 'lfitfunction' data */ int nlfunct; int omajor; psnsym *varsym,*mysyms[8]; lfitdata lf_static,*lf=&lf_static; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; for ( i=0 ; psnlfit_list_builtin_normal_operators[i].name != NULL ; i++ ) { int r; r=lfit_register_internal(&psnlfit_list_builtin_normal_operators[i]); if ( r ) { fprint_error("unable to register a built-in operator, exiting"); return(1); } } for ( i=0 ; psnlfit_list_builtin_elementary_functions[i].name != NULL ; i++ ) { int r; r=lfit_register_internal(&psnlfit_list_builtin_elementary_functions[i]); if ( r ) { fprint_error("unable to register a built-in function, exiting"); return(1); } } for ( i=0 ; psnlfit_list_builtin_interpolators[i].name != NULL ; i++ ) { int r; r=lfit_register_internal(&psnlfit_list_builtin_interpolators[i]); if ( r ) { fprint_error("unable to register a built-in interpolator function, exiting"); return(1); } } for ( i=0 ; psnlfit_list_builtin_aa_functions[i].name != NULL ; i++ ) { int r; r=lfit_register_internal(&psnlfit_list_builtin_aa_functions[i]); if ( r ) { fprint_error("unable to register an additional built-in analytic function, exiting"); return(1); } } #if defined _FITSH_SOURCE || defined _ASTRO_EXTEN for ( i=0 ; psnlfit_list_builtin_xfuncts[i].name != NULL ; i++ ) { int r; r=lfit_register_internal(&psnlfit_list_builtin_xfuncts[i]); if ( r ) { fprint_error("unable to register an extra built-in function, exiting"); return(1); } } #endif is_verbose=is_dump_delta=is_help=0; varstr=colstr=fncstr=depstr=errstr=cntstr=NULL; formatstr=NULL; corrfmstr=NULL; vardiffstr=NULL; varseplist=NULL; xdefinelist=NULL; lf->parameters.fit_method=FIT_METHOD_CLLS; /* default: CLLS */ submethodstr=NULL; /* -P|--parameters: finetune */ /* common for many MC method (MCMC, XMMC, EMCE): */ lf->parameters.mc_iterations=1000; /* NLLM, LMND: */ lf->parameters.tune.nllm.lambda=0.001, /* lambda initial */ lf->parameters.tune.nllm.lambda_mpy=10.0, /* lambda multiplicator */ lf->parameters.tune.nllm.max_iter=10; /* NLLM interations */ lf->parameters.tune.nllm.numeric_derivs=0; /* NLLM or LMND? */ /* DHSX: */ lf->parameters.tune.dhsx.use_fisher_sx=0; /* default: no need for */ /* partial derivatives but */ /* some initial uncertainties*/ /* MCMC: */ lf->parameters.tune.mcmc.use_gibbs=0; /* default: normal sampler */ lf->parameters.tune.mcmc.count_accepted=1; /* default: count accepted */ /* XMMC: */ lf->parameters.tune.xmmc.skip_initial_fit=0; /* skip initial XMMC/DHSX fit*/ lf->parameters.tune.xmmc.is_adaptive=0; /* default: non-adaptive XMMC*/ lf->parameters.tune.xmmc.count_accepted=1; /* default: count accepted */ lf->parameters.tune.xmmc.window=16; /* for a nice fit, it's fine */ lf->parameters.tune.xmmc.niter=0; /* no additional iteratiosn */ /* EMCE: */ lf->parameters.tune.emce.skip_initial_fit=0; /* skip initial EMCE fit */ lf->parameters.tune.emce.sub_method=FIT_METHOD_DHSX; /* FIMA: */ lf->parameters.tune.fima.do_montecarlo=0; lf->parameters.tune.fima.write_original=1; lf->parameters.tune.fima.write_uncert=1; lf->parameters.tune.fima.write_correl=1; lf->parameters.niter=0; /* default: no n-sigma rejection */ lf->parameters.sigma=3.0; /* default sigma level: 3 */ ofname=obname=oaname=oxname=ovname=outname=inname=NULL; errdump=0; resdump=-1; /* dynamlic extensions: */ dliblist=NULL;(void)dliblist; /* function, dependent expr, errors, columns, adjusted variables...:*/ fncstr=depstr=errstr=colstr=varstr=dvrstr=NULL; inp_keys=inp_args=NULL; col_keys=col_args=NULL; fnc_keys=fnc_args=NULL; dep_keys=dep_args=NULL; err_keys=err_args=NULL; wgt_keys=wgt_args=NULL; clostr=NULL; perturbstr=NULL; is_fit=0; is_weighted_sigma=0; errtype=0; seed=0; /* random seed for MCMC/EMCE/XMMC and the random functions */ is_warn_obsolete=0; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, /* free letters: [gm] */ /* general informative options: */ "-h|--help|--short-help|--help-short:%SN1f",&is_help, "--example|--examples:%SN2f",&is_help, "--version:%SN-1f",&is_help, "--version-short|--short-version:%SN-2f",&is_help, "--function-list|--functions|--list|--function|--list-functions:%SN3f",&is_help, "--long-help|--help-long:%SN4f",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN5f%q",&is_help, /* options declaring outputs: */ "-o|--output:%s",&outname, "-u|--output-fitted:%s",&ofname, "-j|--output-rejected:%s",&obname, "-a|--output-all:%s",&oaname, "-p|--output-expression:%s",&oxname, "-l|--output-variables|--output-vars:%s",&ovname, "--delta:%SN1f",&is_dump_delta, "--delta-comment:%SN-1f",&is_dump_delta, /* ! */ "-of:%s%f",&ofname,&is_warn_obsolete, /* ! */ "-or:%s%f",&obname,&is_warn_obsolete, /* ! */ "-oa:%s%f",&oaname,&is_warn_obsolete, /* ! */ "-ox:%s%f",&oxname,&is_warn_obsolete, /* ! */ "-ov:%s%f",&ovname,&is_warn_obsolete, /* ! */ "-om:%s%f",&outname,&is_warn_obsolete, /* fitting methods: */ "-L|--clls|--linear:" SNf(FIT_METHOD_CLLS),&lf->parameters.fit_method, "-N|--nllm|--nonlinear:"SNf(FIT_METHOD_NLLM),&lf->parameters.fit_method, "-M|--mcmc:" SNf(FIT_METHOD_MCMC),&lf->parameters.fit_method, "-K|--mchi|--chi2:" SNf(FIT_METHOD_MCHI),&lf->parameters.fit_method, "-E|--emce:" SNf(FIT_METHOD_EMCE),&lf->parameters.fit_method, "-D|--dhsx|--downhill:" SNf(FIT_METHOD_DHSX),&lf->parameters.fit_method, "-X|--xmmc:" SNf(FIT_METHOD_XMMC),&lf->parameters.fit_method, "-U|--lmnd:" SNf(FIT_METHOD_LMND),&lf->parameters.fit_method, "-A|--fima:" SNf(FIT_METHOD_FIMA),&lf->parameters.fit_method, /* Fine tune: */ /* ! */ "-S|--emce-fit-method:%s%f",&submethodstr,&is_warn_obsolete, "-P|--param|--params|--parameters:%s",&submethodstr, "-s|--seed:%d",&seed, "--perturbations:%s",&perturbstr, "-i|--mcmc-iterations|--emce-iterations|--xmmc-iterations|--fima-iterations:%d",&lf->parameters.mc_iterations, "-k|--separate:%Cr",&varseplist, /* variables to fit or analyze: */ "-v|--var|--vars|--variable|--variables:%Cr",&varstr, "-g|--derived-variable|--derived-variables:%Cr",&dvrstr, "-F|--format:%Cr",&formatstr, "-C|--correlation-format:%s",&corrfmstr, "-q|--difference|--differences:%Cr",&vardiffstr, #ifdef LFIT_ENABLE_DYNAMIC_EXTENSIONS "-d|--dynamic:%Dt",&dliblist, #endif /* input: input content format, specifications of the columns: */ "-c|--col|--cols|--column|--columns:%m",&colstr, "-c[0-9a-zA-Z]*:%Dl%Dt",&col_keys,&col_args, "-z|--columns-output|--column-output|--col-out:%s",&clostr, /* input: function to be fitted: */ "-f|--funct|--function:%Cr",&fncstr, "-f[0-9a-zA-Z]*:%Dl%Dt",&fnc_keys,&fnc_args, /* input: dependent variable: */ "-y|--dep|--dependent:%m",&depstr, "-y[0-9a-zA-Z]*:%Dl%Dt",&dep_keys,&dep_args, /* input: errors or weights to be used: */ "-e|--error:%SN0f%m",&errtype,&errstr, "-e[0-9a-zA-Z]*:%Dl%Dt",&err_keys,&err_args, "-w|--weight:%SN1f%m",&errtype,&errstr, "-w[0-9a-zA-Z]*:%Dl%Dt",&wgt_keys,&wgt_args, /* linear constraints between the fitted variables: */ "-t|--constraint|--constraints:%Cr",&cntstr, /* additional, user defined macros/functions: */ "-x|--define|--macro:%Dt",&xdefinelist, /* fit error outputs: */ "--err|--errors|--error-rows:%SN1f",&errdump, "--err-lin|--error-line:%SN2f",&errdump, "--err-col|--error-columns:%SN3f",&errdump, "--res|--residual:" SNf(RESIDUAL_BIASED) ,&resdump, "--unbiased-residual:" SNf(RESIDUAL_UNBIASED) ,&resdump, "--residual-unbiased:" SNf(RESIDUAL_UNBIASED) ,&resdump, "--residual-chi2:" SNf(RESIDUAL_CHI2) ,&resdump, "--unbiased-chi2:" SNf(RESIDUAL_UNBIASED_CHI2) ,&resdump, /* parameters of the sigma rejection: */ "-n|--iterations:%d",&lf->parameters.niter, "-r|--sigma|--rejection|--rejection-level:%g",&lf->parameters.sigma, "--weighted-sigma:%f",&is_weighted_sigma, /* other remaining options, error handling, input file, ...: */ "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "--quiet:%SN-1f",&is_verbose, "-i[0-9a-zA-Z]*:%Dl%Dt",&inp_keys,&inp_args, "-:%w",&inname, "+*|-*:%e", "*:%w",&inname, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help==1 ) { fprint_lfit_usage(stderr); return(0); } else if ( is_help==2 ) { fprint_lfit_examples(stdout); return(0); } else if ( is_help==3 ) { fprint_lfit_function_list(stdout, (psnlfit *)psnlfit_list_builtin_normal_operators, (psnlfit *)psnlfit_list_builtin_elementary_functions, (psnlfit *)psnlfit_list_builtin_interpolators, (psnlfit *)psnlfit_list_builtin_aa_functions, #if defined _FITSH_SOURCE || defined _ASTRO_EXTEN (psnlfit *)psnlfit_list_builtin_xfuncts, #endif NULL); return(0); } else if ( is_help==4 ) { fprint_lfit_long_help(stdout,0); return(0); } else if ( is_help==5 ) { fprint_lfit_long_help(stdout,1); return(0); } else if ( is_help<-1 ) { fprintf(stdout,"lfit-%s [fitsh-%s]\n",LFIT_VERSION,FITSH_VERSION); return(0); } else if ( is_help<0 ) { fprintf(stdout,"lfit %s (%s)\n",LFIT_VERSION,LFIT_LASTCHANGE); fprintf(stdout,"Copyright (C) 1996, 2002, 2004-2008, 2009; Pal, Andras \n"); return(0); } if ( is_warn_obsolete ) { fprintf(stderr,"Warning: you have specified some of the following command line arguments:\n"); fprintf(stderr,"\t-of\t-ox\t-ov\t-or\t-oa\t-om\t-S\n"); fprintf(stderr,"Note that these arguments are obsolete and will have different effects in the\n"); fprintf(stderr,"further releases of `lfit`. Please use these respective arguments instead:\n"); fprintf(stderr,"\t-u\t-p\t-l\t-j\t-a\t-o\t-P\n"); } if ( lf->parameters.fit_method==FIT_METHOD_EMCE && submethodstr != NULL ) { int is_default; is_default=0; /* de facto dummy variable */ i=scanpar(submethodstr,SCANPAR_DEFAULT, "default|defaults:%f",&is_default, "clls|linear:" SNf(FIT_METHOD_CLLS), &lf->parameters.tune.emce.sub_method, "nllm|nonlinear:" SNf(FIT_METHOD_NLLM), &lf->parameters.tune.emce.sub_method, "lmnd:" SNf(FIT_METHOD_LMND), &lf->parameters.tune.emce.sub_method, "dhsx|downhill:" SNf(FIT_METHOD_DHSX), &lf->parameters.tune.emce.sub_method, "mcmc|mc|montecarlo:" SNf(FIT_METHOD_MCMC), &lf->parameters.tune.emce.sub_method, "fisher:%f", &lf->parameters.tune.dhsx.use_fisher_sx, "skip:%f",&lf->parameters.tune.emce.skip_initial_fit, NULL); if ( i ) { fprint_error("invalid parameter argument in '%s'",submethodstr); return(1); } } else if ( (lf->parameters.fit_method==FIT_METHOD_NLLM || lf->parameters.fit_method==FIT_METHOD_LMND) && submethodstr != NULL ) { int is_default; is_default=0; /* de facto dummy variable */ i=scanpar(submethodstr,SCANPAR_DEFAULT, "default|defaults:%f",&is_default, "lambda:%g" ,&lf->parameters.tune.nllm.lambda, "multiply:%g" ,&lf->parameters.tune.nllm.lambda_mpy, "iterations:%d" ,&lf->parameters.tune.nllm.max_iter, NULL); if ( lf->parameters.fit_method==FIT_METHOD_LMND ) lf->parameters.tune.nllm.numeric_derivs=1; else lf->parameters.tune.nllm.numeric_derivs=0; if ( i ) { fprint_error("invalid parameter argument in '%s'",submethodstr); return(1); } } else if ( lf->parameters.fit_method==FIT_METHOD_MCMC && submethodstr != NULL ) { int is_default; is_default=0; /* de facto dummy variable */ i=scanpar(submethodstr,SCANPAR_DEFAULT, "default|defaults:%f",&is_default, "accepted:%f", &lf->parameters.tune.mcmc.count_accepted, "nonaccepted:%SN0f",&lf->parameters.tune.mcmc.count_accepted, "gibbs:%f",&lf->parameters.tune.mcmc.use_gibbs, NULL); if ( i ) { fprint_error("invalid parameter argument in '%s'",submethodstr); return(1); } } else if ( lf->parameters.fit_method==FIT_METHOD_DHSX && submethodstr != NULL ) { int is_default; is_default=0; /* de facto dummy variable */ i=scanpar(submethodstr,SCANPAR_DEFAULT, "default|defaults:%f",&is_default, "fisher:%f",&lf->parameters.tune.dhsx.use_fisher_sx, NULL); if ( i ) { fprint_error("invalid parameter argument in '%s'",submethodstr); return(1); } } else if ( lf->parameters.fit_method==FIT_METHOD_XMMC && submethodstr != NULL ) { int is_default; is_default=0; /* de facto dummy variable */ i=scanpar(submethodstr,SCANPAR_DEFAULT, "default|defaults:%f",&is_default, "accepted:%f", &lf->parameters.tune.xmmc.count_accepted, "nonaccepted:%SN0f",&lf->parameters.tune.xmmc.count_accepted, "skip:%f", &lf->parameters.tune.xmmc.skip_initial_fit, "adaptive:%f", &lf->parameters.tune.xmmc.is_adaptive, "window:%d", &lf->parameters.tune.xmmc.window, "iterations:%d",&lf->parameters.tune.xmmc.niter, NULL); if ( i ) { fprint_error("invalid parameter argument in '%s'",submethodstr); return(1); } if ( lf->parameters.tune.xmmc.is_adaptive && lf->parameters.tune.xmmc.niter>0 ) { fprint_error("sorry, simultaneous adaptive and iterative XMMC is incompatible"); return(1); } } else if ( lf->parameters.fit_method==FIT_METHOD_FIMA && submethodstr != NULL ) { int is_default,wo,wu,wc; is_default=0; /* de facto dummy variable */ wo=wu=wc=-1; i=scanpar(submethodstr,SCANPAR_DEFAULT, "default|defaults:%f",&is_default, "mc|montecarlo:%f",&lf->parameters.tune.fima.do_montecarlo, "orig|original:%SN1f",&wo, "noorig|nooriginal:%SN0f",&wo, "error|errors|uncert|uncertainty|uncertainties:%SN1f",&wu, "noerror|noerrors|nouncert|nouncertainty|nouncertainties:%SN0f",&wu, "corr|correl|correlation|correlations:%SN1f",&wc, "nocorr|nocorrel|nocorrelation|nocorrelations:%SN0f",&wc, NULL); if ( i ) { fprint_error("invalid parameter argument in '%s'",submethodstr); return(1); } if ( ! wo ) lf->parameters.tune.fima.write_original=0; else if ( wo>0 ) lf->parameters.tune.fima.write_original=1; if ( ! wu ) lf->parameters.tune.fima.write_uncert=0; else if ( wu>0 ) lf->parameters.tune.fima.write_uncert=1; if ( ! wc ) lf->parameters.tune.fima.write_correl=0; else if ( wc>0 ) lf->parameters.tune.fima.write_correl=1; } if ( ! lf->parameters.fit_method ) force_nonlin=0; else if ( lf->parameters.fit_method==FIT_METHOD_CLLS ) force_nonlin=0; else if ( lf->parameters.fit_method==FIT_METHOD_EMCE && lf->parameters.tune.emce.sub_method==FIT_METHOD_CLLS ) force_nonlin=0; else force_nonlin=1; ldyns=NULL; nldyn=0; (void)ldyns; (void)nldyn; lfuncts=NULL; nlfunct=0; #ifdef LFIT_ENABLE_DYNAMIC_EXTENSIONS for ( i=0 ; dliblist != NULL && dliblist[i] != NULL ; i++ ) { void *handle; char *dlibspec,*p,*n; lfitfunction *lff; int j; dlibspec=strdup(dliblist[i]); p=strchr(dlibspec,':'); if ( p==NULL ) { fprint_warning("no function array specifications after '%s', skipped",dlibspec); free(dlibspec); continue; } *p=0; p++; handle=dlopen(dlibspec,RTLD_NOW); if ( handle==NULL ) { fprint_warning("unable to load shared library '%s' (%s), skipped",dlibspec,dlerror()); free(dlibspec); continue; } ldyns=(lfitdynlib *)realloc(ldyns,sizeof(lfitdynlib)*(nldyn+1)); ldyns[nldyn].file=dliblist[i]; ldyns[nldyn].handle=handle; nldyn++; while ( p != NULL && (*p) ) { while ( isspace((int)(*p)) ) p++; n=strchr(p,','); if ( n != NULL ) { *n=0; n++; } lff=(lfitfunction *)dlsym(handle,p); if ( lff==NULL ) { fprint_warning("function array '%s' cannot be found in '%s', skipped",p,dlibspec); j=0; } else { for ( j=0 ; lff[j].name != NULL && lff[j].function != NULL ; ) j++; } if ( j>0 ) { lfuncts=(lfitfunction *)realloc(lfuncts,sizeof(lfitfunction)*(nlfunct+j)); memcpy(lfuncts+nlfunct,lff,sizeof(lfitfunction)*j); nlfunct+=j; } p=n; }; free(dlibspec); } #endif lpg.lffregs=NULL; lpg.nlffreg=0; omajor=LFIT_F_MAX_BUILTIN; if ( lfuncts != NULL && 0name) ) { fprint_error("function name '%s' (from a dynamically loaded library) contains unexpected character(s)",lff->name); return(1); } else if ( lfit_register_symbol_exists(&lpg,lff->name) ) { fprint_error("function name '%s' (from a dynamically loaded library) has already been in use",lff->name); return(1); } if ( lff->flags & LFITFUNCTION_DIFFERENTIABLE ) { int i,j,p,n; p=0; n=lff->nvar+lff->nidv; diffrule=(short *)malloc(sizeof(short)*lff->nvar*(n+4)); for ( i=0 ; invar ; i++ ) { for ( j=0 ; j0 ) diffrule[p]=O_ADD,p++; } diffrule[p]=0; } else diffrule=NULL; lfit_register_function(lff->name,omajor,lff->nvar+lff->nidv,f_lfitfunction_generic,diffrule,NULL); lpg.lffregs=(lffreg *)realloc(lpg.lffregs,sizeof(lffreg)*(lpg.nlffreg+1)); lr=&lpg.lffregs[lpg.nlffreg]; lr->lff=lff; lr->fmajor=omajor; omajor++; if ( lff->flags & LFITFUNCTION_DIFFERENTIABLE ) { int i; for ( i=0 ; invar ; i++ ) { lfit_register_function(NULL,omajor+i,lff->nvar+lff->nidv,f_lfitfunction_generic,NULL,NULL); } omajor += lff->nvar; } lr->nmajor=omajor; lr->diff=NULL; lpg.nlffreg++; } } if ( xdefinelist != NULL ) { char **xdef; for ( xdef=xdefinelist ; *xdef ; xdef++ ) { lfit_define_macro(lf,*xdef,&omajor); } } if ( varstr != NULL ) { remove_spaces_and_comments(varstr); extract_variables(varstr,&vars,&nvar); } else { vars=NULL, nvar=0; } for ( i=0 ; vars != NULL && i0 && ( colstr != NULL || fncstr != NULL || depstr != NULL || errstr != NULL ) ) { fprint_error("invalid combination of input fit data"); return(1); } if ( nkey>0 ) { int i,k,l,r,is_l_fit; char *key,*arg,*arg2,*c; datablock *db; lf->ndatablock=nkey; lf->datablocks=(datablock *)malloc(sizeof(datablock)*lf->ndatablock); is_fit=0; for ( i=0 ; idatablocks[i]; db->key=key; arg=key_search_argument(inp_keys,2,key,inp_args); /* no input argument found: */ if ( arg==NULL ) { fprint_error("input file name is missing, use -i 'filename' to define"); return(1); } db->inparg=arg; /* no column definition found: */ arg=key_search_argument(col_keys,2,key,col_args); if ( arg==NULL ) { fprint_error("column definitions missing, use -c 'cols' to define"); return(1); } db->colarg=strdup(arg); if ( extract_columns(db->colarg,&db->cols,&db->ncol) ) { fprint_error("invalid column specification in '%s' (note that each column can only be defined once)",arg); return(1); } for ( k=0,r=0 ; kncol && (! r) ; k++ ) { if ( db->cols[k].name==NULL || strlen(db->cols[k].name)<=0 ) continue; if ( lfit_check_symbol_name(db->cols[k].name) ) { r=db->ncol+k+1; break; } else if ( lfit_register_symbol_exists(&lpg,db->cols[k].name) ) { r=k+1; break; } for ( l=0 ; lcols[l].name==NULL || strlen(db->cols[l].name)<=0 ) continue; if ( strcmp(db->cols[l].name,db->cols[k].name)==0 ) { r=-k-1; break; } } } if ( r>db->ncol ) { fprint_error("column name '%s' contains unexpected character(s)",db->cols[r-db->ncol-1].name); return(1); } else if ( r>0 ) { fprint_error("column name '%s' has already been used as a function, macro or variable name",db->cols[r-1].name); return(1); } else if ( r<0 ) { fprint_error("column name '%s' has already been used as a name of another column",db->cols[(-r)-1].name); return(1); } arg=key_search_argument(fnc_keys,2,key,fnc_args); if ( arg==NULL ) { fprint_error("fit function is missing, use -f 'func' to define one"); return(1); } db->fncarg=strdup(arg); arg=key_search_argument(dep_keys,2,key,dep_args); if ( arg != NULL ) db->deparg=strdup(arg); else db->deparg=NULL; for ( c=db->fncarg ; *c ; c++ ) { if ( *c=='=' ) break; } if ( *c=='=' && db->deparg != NULL ) { fprint_error("dependent value missing or ambigous, use -y 'expr' or -f '...=expr' to define"); return(1); } else if ( *c=='=' ) { *c=0,c++; db->deparg=strdup(c); } if ( db->deparg != NULL ) is_l_fit=1,is_fit++; else is_l_fit=0; if ( ! nvar && is_l_fit ) { fprint_error("definition of fit variables missing, use -v 'vars' to define"); return(1); } arg =key_search_argument(err_keys,2,key,err_args); arg2=key_search_argument(wgt_keys,2,key,wgt_args); if ( arg != NULL && arg2 != NULL ) { fprint_error("both error and weight have been defined, use only one of them"); return(1); } else if ( arg != NULL ) db->errarg=strdup(arg), db->errtype=0; else if ( arg2 != NULL ) db->errarg=strdup(arg2), db->errtype=!0; else db->errarg=NULL, db->errtype=0; } if ( is_fit && is_fit < nkey ) { fprint_error("input file name is missing, use -i 'filename' to define"); return(1); } } else { datablock *db; char *c; int k,l,r; lf->ndatablock=1; lf->datablocks=(datablock *)malloc(sizeof(datablock)); db=&lf->datablocks[0]; if ( colstr==NULL ) { fprint_error("column definitions missing, use -c 'cols' to define"); return(1); } if ( extract_columns(colstr,&db->cols,&db->ncol) ) { fprint_error("invalid column specification in '%s' (note that each column can only be defined once)",colstr); return(1); } for ( k=0,r=0 ; kncol && (! r) ; k++ ) { if ( db->cols[k].name==NULL || strlen(db->cols[k].name)<=0 ) continue; if ( lfit_check_symbol_name(db->cols[k].name) ) { r=db->ncol+k+1; break; } else if ( lfit_register_symbol_exists(&lpg,db->cols[k].name) ) { r=k+1; break; } for ( l=0 ; lcols[l].name==NULL || strlen(db->cols[l].name)<=0 ) continue; if ( strcmp(db->cols[l].name,db->cols[k].name)==0 ) { r=-k-1; break; } } } if ( r>db->ncol ) { fprint_error("column name '%s' contains unexpected character(s)",db->cols[r-db->ncol-1].name); return(1); } if ( r>0 ) { fprint_error("column name '%s' has already been used as a function, macro or variable name",db->cols[r-1].name); return(1); } else if ( r<0 ) { fprint_error("column name '%s' has already been used as a name of another column",db->cols[(-r)-1].name); return(1); } db->colarg=colstr; if ( fncstr==NULL ) { fprint_error("fit function is missing, use -f 'func' to define one"); return(1); } for ( c=fncstr ; *c ; c++ ) { if ( *c=='=' ) break; } if ( *c=='=' && depstr != NULL ) { fprint_error("dependent value missing or ambigous, use -y 'expr' or -f '...=expr' to define"); return(1); } else if ( *c=='=' ) { *c=0,c++; depstr=strdup(c); } if ( depstr != NULL ) is_fit=1; else is_fit=0; if ( ! nvar && is_fit ) { fprint_error("definition of fit variables missing, use -v 'vars' to define"); return(1); } db->fncarg=fncstr; db->deparg=depstr; db->errtype=errtype; db->errarg=errstr; db->inparg=inname; db->key="default"; } /* random() and gaussian() functions are only available in evaluation mode: */ if ( ! is_fit ) { int r; r=lfit_register_random_functions(); if ( r ) { fprint_error("unable to register a random number generator function, exiting"); return(1); } } if ( formatstr != NULL && is_fit ) { i=extract_variable_formats(formatstr,vars,nvar,dvars,ndvar); if ( i ) { fprint_error("invalid variable format string"); return(1); } } if ( corrfmstr != NULL ) { if ( corrfmstr[0]=='%' ) corrfmstr++; if ( strlen(corrfmstr)>14 || format_check(corrfmstr) ) { fprint_error("invalid variable format string"); return(1); } lf->corrfm[0]='%'; strncpy(lf->corrfm+1,corrfmstr,15); } else strcpy(lf->corrfm,LFIT_DEFAULT_CORR_FORMAT); if ( vardiffstr != NULL ) { i=extract_variable_differences(vardiffstr,vars,nvar); if ( i ) { fprint_error("invalid parameter for variable differences (required by numeric derivative estimations0"); return(1); } for ( i=0 ; imaxncol=0; for ( i=0 ; indatablock ; i++ ) { if ( lf->maxncol < lf->datablocks[i].ncol ) lf->maxncol=lf->datablocks[i].ncol; } if ( outname != NULL ) { fw=fopenwrite(outname); if ( fw==NULL ) { fprint_error("unable to create output file '%s'",outname); return(1); } } else fw=NULL; varsym=(psnsym *)malloc(sizeof(psnsym)*(nvar+1)); for ( i=0 ; ivarsym=varsym; for ( i=0 ; dvars != NULL && iname); return(1); } else if ( r==2 ) { fprint_error("syntax error in the definition function of the derived variable '%s'",wv->name); return(1); } else if ( r>=3 ) { fprint_error("non-differentiable expression in the definition function of the derived variable '%s'",wv->name); return(1); } else if ( r ) { fprint_error("unknown error in the definition function of the derived variable '%s'",wv->name); return(1); } } for ( i=0 ; indatablock ; i++ ) { datablock *db; int j; psnsym *colsym; db=&lf->datablocks[i]; colsym=(psnsym *)malloc(sizeof(psnsym)*(db->ncol+1)); for ( j=0 ; jncol ; j++ ) { colsym[j].type=T_VAR; colsym[j].major=j+nvar; colsym[j].name=db->cols[j].name; } colsym[db->ncol].type=0; colsym[db->ncol].major=0; colsym[db->ncol].name=NULL; db->colsym=colsym; } if ( is_fit ) { mysyms[0]=varsym, mysyms[1]=lpg.pl_sym, mysyms[2]=NULL; i=build_psn_constraint_sequences(lf,cntstr,mysyms,vars,nvar); if ( i ) exit_with_usage(i); if ( lf->fconstraint.nc > nvar ) { fprint_error("too many constraints"); return(1); } } for ( i=0 ; indatablock ; i++ ) lf->datablocks[i].xnoise=0.0; /* no extra (white)noise by default */ if ( perturbstr != NULL ) { int i,n; double xnoise; if ( nkey>0 ) { char *tmp,**cmd,*arg[4]; datablock *db; tmp=strdup(perturbstr); cmd=tokenize_char_dyn(tmp,','); for ( i=0 ; cmd != NULL && cmd[i] != NULL ; i++ ) { n=tokenize_char(cmd[i],arg,':',2); if ( n<2 ) { fprint_error("invalid syntax in the perturbation parameters"); return(1); } db=datablock_search_by_key(lf,arg[0]); if ( db==NULL ) { fprint_error("invalid datablock key '%s'",arg[0]); return(1); } if ( sscanf(arg[1],"%lg",&xnoise)<1 || xnoise<0.0 ) { fprint_error("invalid noise level '%s' near datablock key '%s'",arg[1],arg[0]); return(1); } db->xnoise=xnoise; } if ( cmd != NULL ) free(cmd); free(tmp); } else if ( lf->ndatablock <= 0 ) { fprint_error("no datablocks are defined"); return(1); } else { if ( sscanf(perturbstr,"%lg",&xnoise)<1 || xnoise<0.0 ) { fprint_error("invalid noise level '%s'",perturbstr); return(1); } lf->datablocks[0].xnoise=xnoise; } } mysyms[0]=varsym, /* symbols for fit variables */ mysyms[1]=NULL, /* gonna be replaced by column symbol table */ mysyms[2]=lpg.pl_sym, /* general operators */ mysyms[3]=NULL; if ( seed<0 ) { struct timeval tv; int fd; if ( (fd=open("/dev/urandom",O_RDONLY)) >= 0 ) { (void)read(fd,&seed,sizeof(int)); close(fd); } else { gettimeofday(&tv,NULL); seed=tv.tv_usec | ((tv.tv_sec & 0xFFF) << 20); } } random_seed(seed); if ( ! is_fit ) { datablock *db; int j; for ( i=0 ; indatablock ; i++ ) { db=&lf->datablocks[i]; mysyms[1]=db->colsym; j=build_psn_base_sequences(db,db->fncarg,lfuncts,nlfunct,mysyms,nvar); if ( j ) exit_with_usage(j); } if ( fw==NULL ) of.f_write=stdout; else of.f_write=fw; if ( clostr != NULL /* && (! lf->parameters.map_chi2) */ ) { ncolout=0; colouts=NULL; while ( *clostr ) { if ( sscanf(clostr,"%d",&i)<1 || i<=0 ) break; colouts=(int *)realloc(colouts,sizeof(int)*(ncolout+1)); colouts[ncolout]=i-1; ncolout++; while ( isdigit((int)*clostr) ) clostr++; if ( *clostr==',' ) clostr++; }; } else { ncolout=0; colouts=NULL; } for ( i=0 ; indatablock ; i++ ) { db=&lf->datablocks[i]; if ( db->inparg==NULL || strcmp(db->inparg,"-")==0 ) fr=stdin; else fr=fopen(db->inparg,"rb"); if ( fr==NULL ) { fprint_error("unable to open input file"); return(1); } evaluate_and_dump(fr,of.f_write,db,vars,nvar,colouts,ncolout,exprs,nexpr); if ( indatablock-1 ) fprintf(of.f_write,"\n"); fcloseread(fr); } } else { FILE *fo,*fb,*fa,*fx,*fv; int i,j,calc_derivatives; datablock *db; calc_derivatives=lfit_is_method_requries_derivatives(lf->parameters.fit_method); if ( lf->parameters.fit_method==FIT_METHOD_EMCE ) calc_derivatives|=lfit_is_method_requries_derivatives(lf->parameters.tune.emce.sub_method); lf->is_linear=1; for ( i=0 ; indatablock ; i++ ) { db=&lf->datablocks[i]; mysyms[1]=db->colsym; j=build_psn_fit_sequences(db,db->fncarg,db->deparg, lfuncts,nlfunct, db->errarg, mysyms,vars,nvar,force_nonlin,calc_derivatives); if ( j ) exit_with_usage(j); if ( ! db->is_linear ) lf->is_linear=0; } if ( varseplist != NULL ) lfit_set_separated_linears(&lf->fconstraint,vars,nvar,varseplist); if ( ofname != NULL ) { fo=fopenwrite(ofname); if ( fo==NULL ) { fprint_error("unable to create output list file '%s' for fitted lines",ofname); return(1); } } else fo=NULL; if ( obname != NULL ) { fb=fopenwrite(obname); if ( fb==NULL ) { fprint_error("unable to create output list file '%s' for rejected lines",obname); return(1); } } else fb=NULL; if ( oaname != NULL ) { fa=fopenwrite(oaname); if ( fa==NULL ) { fprint_error("unable to create output list file '%s' for used lines",oaname); return(1); } } else fa=NULL; if ( oxname != NULL ) { fx=fopenwrite(oxname); if ( fx==NULL ) { fprint_error("unable to create output expression file '%s'",oxname); return(1); } } else fx=NULL; if ( ovname != NULL ) { fv=fopenwrite(ovname); if ( fv==NULL ) { fprint_error("unable to create variable list file"); return(1); } } else fv=NULL; if ( fo==NULL && fb==NULL && fx==NULL && fw==NULL && fa==NULL && fv==NULL ) fw=stdout; if ( lf->parameters.niter<=0 ) lf->parameters.niter=0; if ( lf->parameters.sigma<=0.0 ) { lf->parameters.niter=0, lf->parameters.sigma=0.0; } of.f_write=fw; of.f_lused=fo; of.f_lrejd=fb; of.f_lall =fa; of.f_expr =fx; of.f_vval =fv; switch ( lf->parameters.fit_method ) { case FIT_METHOD_MCMC: fit_markov_chain_monte_carlo(lf,&of,vars,nvar); break; case FIT_METHOD_MCHI: fit_map_chi2(lf,&of,vars,nvar); break; case FIT_METHOD_EMCE: fit_error_monte_carlo_estimation(lf,&of,vars,nvar); break; case FIT_METHOD_XMMC: fit_extended_markov_chain_mc(lf,&of,vars,nvar); break; case FIT_METHOD_DHSX: fit_downhill_simplex(lf,&of,vars,nvar); break; case FIT_METHOD_CLLS: case FIT_METHOD_NLLM: fit_linear_or_nonlinear(lf,&of,vars,nvar, errtype,errdump,resdump,is_dump_delta,is_weighted_sigma,0); break; case FIT_METHOD_LMND: fit_linear_or_nonlinear(lf,&of,vars,nvar, errtype,errdump,resdump,is_dump_delta,is_weighted_sigma,1); break; case FIT_METHOD_FIMA: fit_fisher_matrix_analysis(lf,&of,vars,nvar,dvars,ndvar); break; default: fprint_error("internal: unimplemented fit method (code: %d)",lf->parameters.fit_method); break; } if ( fx != NULL ) fclosewrite(fx); if ( fb != NULL ) fclosewrite(fb); if ( fo != NULL ) fclosewrite(fo); if ( fa != NULL ) fclosewrite(fa); if ( fw != NULL ) fclosewrite(fw); } #ifdef LFIT_ENABLE_DYNAMIC_EXTENSIONS for ( i=nldyn-1 ; i>=0 && ldyns != NULL ; i-- ) { dlclose(ldyns[i].handle); } if ( ldyns != NULL ) free(ldyns); ldyns=NULL; nldyn=0; #endif return(0); } /*****************************************************************************/ fitsh-0.9.2/src/pselect.h0000644000175000017500000000310010667340122013645 0ustar apalapal/*****************************************************************************/ /* pselect.h */ /*****************************************************************************/ #ifndef __PSELECT_H_INCLUDED #define __PSELECT_H_INCLUDED 1 #include "math/point.h" /* point_select(): Selects points from the set 'points' (which contains 'npoint' points). The function tries to select 'nselect' points from the set as homogeneously, as it is declared by 'level'. It is not guaranteed that, even if 'nselect' <= 'npoint', the desired number of points will be selected (it might happen when the initial set is very inhomogeneous). Only the point in the rectangle [x0:x1,y0:y1] will be selected. The array 'ret' is filled by this function with false (zero) or true (nonzero) values: if 'ret[i]' is true, the point 'points[i]' should be treated as a selected one. The number of selected points are returned (which is always less or equal to 'nselect'). The parameter 'level' indicates the desired level, whether homogeneousity or the weightness (indicaded for each point by the field 'weight' in the structure 'point') is more important during the selection. If 'level' is 0, only the 'nselect' points with the highest weights will be selected. The more higher 'level' is, the more homogeneous set will be returned. If 'level' is negative, the function does not take the weights into account. */ int point_select(point *points,int npoint,char *ret,int nselect, double x0,double y0,double x1,double y1,int level); #endif fitsh-0.9.2/src/str.h0000644000175000017500000000257010614467750013041 0ustar apalapal/*****************************************************************************/ /* str.h */ /*****************************************************************************/ #ifndef __STR_H_INCLUDED #define __STR_H_INCLUDED 1 /*****************************************************************************/ /* strkcpy(): It works like strncpy() but ensures that 'out' is zero-terminated (therefore, the length of 'out' is always _less_ than 'max'). */ char * strkcpy(char *out,char *in,int max); /* strappend(): Appends the string 'cat' to the dynamically allocated string 'string'. 'string' can be NULL, in this case, the function works like strdup(). */ int strappend(char **string,char *cat); /* strappendf(): It is a combination of realloc(), strcat() and sprintf(). Appends the printf-formatted argument 'format' to the dynamically allocated string 'string'. It is a bit primitive, therefore use only if long-long strings could not occur (otherwise it also works, but can be slow). */ int strappendf(char **string,char *format,...); /* vstrappendf(): */ int vstrappendf(char **string,char *format,va_list ap); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/history.c0000644000175000017500000000212512771247633013723 0ustar apalapal/*****************************************************************************/ /* history.c */ /*****************************************************************************/ #include #include #include #include #include #include #include #include "fitsh.h" #include "history.h" /*****************************************************************************/ int fits_history_export_command_line(fits *img,char *prg,char *vrs,int argc,char *argv[]) { char buff[64]; time_t t; struct tm *tm; time(&t); tm=localtime(&t); sprintf(buff,"%s: %s [%s@%s] %.4d.%.2d.%.2d %.2d:%.2d:%.2d (%s)", prg,vrs,FITSH_VERSION,FITSH_RELEASE_DATE, tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday, tm->tm_hour,tm->tm_min,tm->tm_sec, (!daylight?tzname[0]:tzname[1])); fits_header_export_command_line(img,"FI_HSTRY",buff,"> ",argc,argv); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/transform.c0000644000175000017500000002761112766533323014242 0ustar apalapal/*****************************************************************************/ /* transform.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Library for parsing and writing transformation files and perform some */ /* related calculations (concerning to inverse transformations, Jacobi's */ /* determinant and so on...). */ /*****************************************************************************/ #include #include #include #include #include #include "math/poly.h" #include "io/iof.h" #include "io/tokenize.h" #include "transform.h" static char *dxfitstr="dxfit", *dyfitstr="dyfit"; /*****************************************************************************/ int transformation_free(transformation *tf) { int i; if ( tf->vfits != NULL ) { for ( i=0 ; inval ; i++ ) { if ( tf->vfits[i] != NULL ) free(tf->vfits[i]); } free(tf->vfits); } return(0); } /*****************************************************************************/ static int transformation_add_vfit(transformation *tf,int v,char *args) { double *fit; int i,nvar; nvar=(tf->order+1)*(tf->order+2)/2; if ( tf->vfits==NULL ) { tf->vfits=(double **)malloc((v+1)*sizeof(double *)); for ( i=0 ; ivfits[i]=NULL; } tf->nval=v+1; } else if ( v>=tf->nval ) { tf->vfits=(double **)realloc(tf->vfits,(v+1)*sizeof(double *)); for ( i=tf->nval ; ivfits[i]=NULL; } tf->nval=v+1; } if ( tf->vfits[v] != NULL ) return(1); fit=(double *)malloc(sizeof(double)*nvar); for ( i=0 ; ivfits[v]=fit; return(0); } static int transformation_check_vfit(transformation *tf) { int i; if ( tf->vfits==NULL || tf->nval<=0 ) return(1); for ( i=0 ; inval ; i++ ) { if ( tf->vfits[i]==NULL ) return(1); } return(0); } int transformation_read_data(FILE *fr,transformation *tf) { char *rbuff,*cmd[4]; int n,type,order,nvar,v; type=0;nvar=-1; rbuff=NULL; while ( ! feof(fr) ) { if ( rbuff != NULL ) free(rbuff); rbuff=freadline(fr); if ( rbuff==NULL ) break; remove_spaces_and_comments(rbuff); if ( strlen(rbuff)==0 ) continue; n=tokenize_char(rbuff,cmd,'=',2); if ( n<2 ) { free(rbuff);return(1); } if ( strcmp(cmd[0],"type")==0 || ! type ) { if ( strcmp(cmd[1],"polynomial")==0 ) { tf->type=type=TRANS_POLYNOMIAL; tf->ox=tf->oy=0.0; /* These parameters are optional */ tf->scale=1.0; /* default values: ox=oy=0, scale=1 */ tf->vfits=NULL; tf->nval=0; nvar=-1; } else { free(rbuff);return(1); } } else if ( ! type ) { free(rbuff);return(5); } else if ( strcmp(cmd[0],"order")==0 ) { if ( sscanf(cmd[1],"%d",&order)<1 ) { free(rbuff);return(5); } tf->order=order; nvar=(order+1)*(order+2)/2; } else if ( strcmp(cmd[0],"offset")==0 ) { if ( sscanf(cmd[1],"%lg,%lg",&tf->ox,&tf->oy)<2 ) { free(rbuff);return(5); } if ( ! isfinite(tf->ox) || ! isfinite(tf->oy) ) { free(rbuff);return(5); } } else if ( strcmp(cmd[0],"scale")==0 ) { if ( sscanf(cmd[1],"%lg",&tf->scale)<1 ) { free(rbuff);return(5); } if ( ! isfinite(tf->scale) ) { free(rbuff);return(5); } } else if ( strcmp(cmd[0],"basisshift")==0 ) { double dummyx,dummyy; if ( sscanf(cmd[1],"%lg,%lg",&dummyx,&dummyy)<2 ) { free(rbuff);return(5); } (void)dummyx; (void)dummyy; } else if ( strcmp(cmd[0],dxfitstr)==0 || strcmp(cmd[0],dyfitstr)==0 ) { if ( strcmp(cmd[0],dxfitstr)==0 ) v=0; else v=1; if ( nvar<=0 ) { free(rbuff);return(5); } if ( transformation_add_vfit(tf,v,cmd[1]) ) { free(rbuff);return(5); } } else if ( sscanf(cmd[0],"vfit:%d",&v)==1 ) { if ( nvar<=0 || v<=0 ) { free(rbuff);return(5); } v--; if ( transformation_add_vfit(tf,v,cmd[1]) ) { free(rbuff);return(5); } } else { free(rbuff);return(5); } } if ( transformation_check_vfit(tf) ) return(1); return(0); } int strlcmp(char *b1,char *b2) { int l; l=strlen(b2); if ( memcmp(b1,b2,l) ) return(1); else return(0); } int transformation_parse_params(char *params,transformation *tf) { int l,ac,v; char *sp,*args; tf->type=0;tf->order=-1; tf->ox=tf->oy=0.0;tf->scale=1.0; tf->vfits=NULL;tf->nval=0; while ( *params ) { for ( l=0,sp=params ; sp[l] && sp[l] != ',' && sp[l] != '=' ; ) l++; if ( sp[l]==',' ) ac=0,args=NULL,params+=l+1; else if ( ! sp[l] ) ac=0,args=NULL,params+=l; else { params+=l+1; args=params;ac=1; while ( *params && ! isalpha((int)*params) ) { if ( *params==',' ) ac++; params++; } if ( isalpha((int)*params) ) ac--; } v=-1; if ( strlcmp(sp,"polynomial")==0 && ac==0 ) { tf->type=TRANS_POLYNOMIAL; tf->vfits=NULL; tf->nval=0; } else if ( strlcmp(sp,"order")==0 && ac==1 ) { if ( sscanf(args,"%d",&tf->order)<1 ) return(1); if ( tf->order<0 ) return(1); } else if ( strlcmp(sp,"scale")==0 && ac==1 ) { if ( sscanf(args,"%lg",&tf->scale)<1 ) return(1); if ( ! isfinite(tf->scale) ) return(1); } else if ( strlcmp(sp,"offset")==0 && ac==2 ) { if ( sscanf(args,"%lg,%lg",&tf->ox,&tf->oy)<2 ) return(1); if ( ! isfinite(tf->ox) || ! isfinite(tf->oy) ) return(1); } else if ( strlcmp(sp,"basisshift")==0 && ac==2 ) { double dummyx,dummyy; if ( sscanf(args,"%lg,%lg",&dummyx,&dummyy)<2 ) return(1); (void)dummyx; (void)dummyy; } else if ( strlcmp(sp,dxfitstr)==0 || strlcmp(sp,dyfitstr)==0 || sscanf(sp,"vfit:%d",&v)==1 ) { if ( strlcmp(sp,dxfitstr)==0 ) v=0; else if ( strlcmp(sp,dyfitstr)==0 ) v=1; else v--; if ( v<0 ) return(1); if ( transformation_add_vfit(tf,v,args) ) return(1); } else return(1); }; if ( transformation_check_vfit(tf) ) return(1); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int transformation_write_coeffs(FILE *fw,double *fit,int nvar) { int i; for ( i=0 ; itype==TRANS_POLYNOMIAL ) { nvar=(tf->order+1)*(tf->order+2)/2; if ( flags&TRANS_WR_COMMENT ) fprintf(fw,"# Type: polynomial of order=%d (number of coefficients: %d)\n",tf->order,nvar); fprintf(fw,"type = polynomial\n"); fprintf(fw,"order = %d\n",tf->order); if ( flags&TRANS_WR_COMMENT ) fprintf(fw,"# Initial transformation of (x_img,y_img):\n"); fprintf(fw,"offset = %g, %g\n",tf->ox,tf->oy); fprintf(fw,"scale = %g\n",tf->scale); if ( tf->nval==2 && (flags&TRANS_WR_DXDY) ) { if ( flags&TRANS_WR_COMMENT ) fprintf(fw,"# Coefficients of the x fit: \n"); fprintf(fw,"%s= ",dxfitstr); transformation_write_coeffs(fw,tf->vfits[0],nvar); if ( flags&(TRANS_WR_IEEE_32|TRANS_WR_IEEE_64) ) { fprintf(fw,"%s-ieee= ",dxfitstr); transformation_write_coeffs_ieee(fw,tf->vfits[0],nvar,flags); } if ( flags&TRANS_WR_COMMENT ) fprintf(fw,"# Coefficients of the y fit: \n"); fprintf(fw,"%s= ",dyfitstr); transformation_write_coeffs(fw,tf->vfits[1],nvar); if ( flags&(TRANS_WR_IEEE_32|TRANS_WR_IEEE_64) ) { fprintf(fw,"%s-ieee= ",dyfitstr); transformation_write_coeffs_ieee(fw,tf->vfits[1],nvar,flags); } } else { if ( flags&TRANS_WR_COMMENT ) fprintf(fw,"# Coefficients: \n"); for ( j=0 ; jnval ; j++ ) { fprintf(fw,"vfit:%d= ",j+1); transformation_write_coeffs(fw,tf->vfits[j],nvar); if ( flags&(TRANS_WR_IEEE_32|TRANS_WR_IEEE_64) ) { fprintf(fw,"vfit:%d-ieee= ",j+1); transformation_write_coeffs_ieee(fw,tf->vfits[j],nvar,flags); } } } } return(0); } /*****************************************************************************/ int transformation_check_if_null(transformation *tf) { int nvar,i,j; if ( tf->type == TRANS_POLYNOMIAL ) { if ( tf->vfits==NULL ) return(-1); nvar=(tf->order+1)*(tf->order+2)/2; for ( i=0 ; inval ; i++ ) { if ( tf->vfits[i]==NULL ) return(-1); for ( j=0 ; jvfits[i][j]) ) return(-1); if ( tf->vfits[i][j] != 0.0 ) return(0); } } return(1); } else return(0); } /*****************************************************************************/ int transformation_get_jacobi(transformation *tf,double **rjxx,double **rjxy,double **rjyx,double **rjyy) { int jnvar,i,j,k; double scale,*jxx,*jxy,*jyx,*jyy; jnvar=(tf->order+0)*(tf->order+1)/2; scale=tf->scale; jxx=(double *)malloc(sizeof(double)*jnvar); jxy=(double *)malloc(sizeof(double)*jnvar); jyx=(double *)malloc(sizeof(double)*jnvar); jyy=(double *)malloc(sizeof(double)*jnvar); for ( i=0 ; iorder-1 ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) { jxx[k]+=tf->vfits[0][k+i+1]/scale; jxy[k]+=tf->vfits[0][k+i+2]/scale; jyx[k]+=tf->vfits[1][k+i+1]/scale; jyy[k]+=tf->vfits[1][k+i+2]/scale; } } *rjxx=jxx, *rjxy=jxy, *rjyx=jyx, *rjyy=jyy; return(0); } int transformation_eval_normal_2d(double x,double y,transformation *tf,double *rx,double *ry) { *rx =eval_2d_poly(x,y,tf->order,tf->vfits[0],tf->ox,tf->oy,tf->scale); *ry =eval_2d_poly(x,y,tf->order,tf->vfits[1],tf->ox,tf->oy,tf->scale); return(0); } #define EPS 1e-10 int transformation_eval_invert_2d(double x,double y,transformation *tf,double *rx,double *ry,double *jxx,double *jxy,double *jyx,double *jyy) { double wx,wy,mxx,mxy,myx,myy,det,imxx,imxy,imyx,imyy,x0,y0,px0,py0,dx,dy; double *px,*py; int i,n; if ( tf->order < 1 ) return(1); px=tf->vfits[0], py=tf->vfits[1]; wx=x-px[0]; wy=y-py[0]; mxx=px[1],mxy=px[2], myx=py[1],myy=py[2]; det=1/(mxx*myy-mxy*myx); imxx=+myy*det; imxy=-mxy*det; imyx=-myx*det; imyy=+mxx*det; x0=imxx*wx+imxy*wy; y0=imyx*wx+imyy*wy; n=100;px0=x0;py0=y0; for ( i=0 ; iorder>=2 ; i++ ) { mxx=eval_2d_poly(x0,y0,tf->order-1,jxx,tf->ox,tf->oy,tf->scale); mxy=eval_2d_poly(x0,y0,tf->order-1,jxy,tf->ox,tf->oy,tf->scale); myx=eval_2d_poly(x0,y0,tf->order-1,jyx,tf->ox,tf->oy,tf->scale); myy=eval_2d_poly(x0,y0,tf->order-1,jyy,tf->ox,tf->oy,tf->scale); det=1/(mxx*myy-mxy*myx); imxx=+myy*det; imxy=-mxy*det; imyx=-myx*det; imyy=+mxx*det; wx=eval_2d_poly(x0,y0,tf->order,px,tf->ox,tf->oy,tf->scale)-x; wy=eval_2d_poly(x0,y0,tf->order,py,tf->ox,tf->oy,tf->scale)-y; dx=imxx*wx+imxy*wy, dy=imyx*wx+imyy*wy; x0-=dx; y0-=dy; if ( fabs(x0-px0)<(fabs(x0)+fabs(px0))*EPS && fabs(y0-py0)<(fabs(y0)+fabs(py0))*EPS ) break; px0=x0, py0=y0; } /* fprintf(stderr,"transform.c: eval_invert_2d(): iterations=%d\n",i); */ *rx=x0; *ry=y0; return(0); } fitsh-0.9.2/src/combine.c0000644000175000017500000003106012771247636013641 0ustar apalapal/*****************************************************************************/ /* combine.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to combining more FITS images. */ /*****************************************************************************/ #include #include #include #include #include #include "fitsh.h" #include "fitsmask.h" #include "io/scanarg.h" #include "statistics.h" #include "tensor.h" #include "combine.h" /*****************************************************************************/ int combine_parse_mode(char *modstr,compar *cp) { int i; double sigma; if ( modstr==NULL ) return(0); sigma=-1.0; i=scanpar(modstr,SCANPAR_DEFAULT, "avg|mean|average:" SNf(COM_MODE_AVG),&cp->mode, "med|median:" SNf(COM_MODE_MED),&cp->mode, "rejavg:" SNf(COM_MODE_REJ_AVG),&cp->mode, "rej|rejmed|rejection:" SNf(COM_MODE_REJ_MED),&cp->mode, "add|sum:" SNf(COM_MODE_SUM),&cp->mode, "sqs|squaresum:" SNf(COM_MODE_SQSUM),&cp->mode, "sct|scatter|stddev:" SNf(COM_MODE_SCT),&cp->mode, "min|minimum:" SNf(COM_MODE_MIN),&cp->mode, "max|maximum:" SNf(COM_MODE_MAX),&cp->mode, "iterations:%d",&cp->niter, "lower:%g",&cp->lower, "upper:%g",&cp->upper, "sigma:%g",&sigma, "or:%SN0f",&cp->logicalmethod, "and:%SN1f",&cp->logicalmethod, "ignorenegative:%N1f",&cp->ignore_flag, "ignorezero:%N2f",&cp->ignore_flag, "ignorepositive:%N4f",&cp->ignore_flag, NULL); if ( sigma>0.0 ) cp->lower=cp->upper=sigma; if ( i ) return(1); else return(0); } /*****************************************************************************/ double do_ordered_rejection(double *points,int n,double m,double w1,double w2, int niter,double lower,double upper,int is_median) { double s,s2,lim; int r; if ( n<=0 || points==NULL ) return(0.0); for ( ; niter > 0 ; niter-- ) { s2=w2+(double)n*m*(m-2.0*w1); if ( s2 <= 0.0 ) return(m); else s=sqrt(s2/(double)n); lim=m-s*lower; r=0; while ( n>0 && *points < lim ) { w1-=*points, w2-=(*points)*(*points); points++,n--; r++; } lim=m+s*upper; while ( n>0 && points[n-1] > lim ) { w1-=points[n-1], w2-=points[n-1]*points[n-1]; n--; r++; } if ( r<=0 ) return(m); else if ( n<=2 ) return(m); else if ( ! is_median ) m=w1/(double)n; else if ( n%2==1 ) m=points[n/2]; else m=0.5*(points[n/2-1]+points[n/2]); } return(m); } double combine_points(double *points,int n,compar *cp) { int i; double w,w1,w2,m; median(points,n); if ( n==0 ) /* All pixels to combine are false. */ return(0.0); else if ( n==1 ) /* One pixel. */ return(points[0]); else if ( cp->mode==COM_MODE_MIN ) { w=points[0]; for ( i=1 ; imode==COM_MODE_MAX ) { w=points[0]; for ( i=1 ; imode==COM_MODE_AVG ) { w=0.0; for ( i=0 ; imode==COM_MODE_SUM ) { w=0.0; for ( i=0 ; imode==COM_MODE_SQSUM ) { w=0.0; for ( i=0 ; imode==COM_MODE_SCT ) { double s,s2; s=s2=0.0; for ( i=0 ; i0.0 ) return(sqrt(s2)); else return(0.0); } else if ( cp->mode==COM_MODE_MED ) { if ( n%2==1 ) w=points[n/2]; else w=0.5*(points[n/2-1]+points[n/2]); return(w); } else if ( cp->mode==COM_MODE_REJ_DEPRECATED ) /* deprecated... see below */ { if ( n==3 ) /* Three, also... */ return(points[1]); else if ( n<=5 ) /* Average of all except the first */ { w=0.0; /* and the last one. */ for ( i=1 ; imode==COM_MODE_REJ_AVG ) { w1=0.0; w2=0.0; for ( i=0 ; initer,cp->lower,cp->upper,0); return(w); } else if ( cp->mode==COM_MODE_REJ_MED ) { w1=0.0; w2=0.0; for ( i=0 ; initer,cp->lower,cp->upper,1); return(w); } else /* Unimplemented method...?! */ return(0.0); } int combine_lines(double **lines,int n,int sx,double *out, compar *cp,char **wmask,char *outmask) { int i,j,k,mw,ow; double *warr,w; warr=(double *)tensor_alloc_1d(double,n); for ( i=0 ; iignore_flag&COM_IGNORE_NEGATIVE) && w<0.0 ) mw|=MASK_FAULT; if ( ! mw ) warr[k]=w,k++; } } else { for ( j=0 ; jignore_flag&COM_IGNORE_NEGATIVE) && w<0.0 ) mw|=MASK_FAULT; if ( ! mw ) warr[k]=w,k++; } } if ( outmask != NULL ) { if ( ! cp->logicalmethod && k>0 ) /* --logical-or */ out[i]=combine_points(warr,k,cp),outmask[i]=0; else if ( cp->logicalmethod && k==n ) /* --logical-and */ out[i]=combine_points(warr,k,cp),outmask[i]=0; else { out[i]=0.0; outmask[i]=(ow?ow:MASK_FAULT); } } else { if ( ! cp->logicalmethod && k>0 ) /* --logical-or */ out[i]=combine_points(warr,k,cp); else if ( cp->logicalmethod && k==n ) /* --logical-and */ out[i]=combine_points(warr,k,cp); else out[i]=0.0; } } tensor_free(warr); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int combine_images_from_files_v1(comimg *inputs,int n,fits *outimg, compar *cp,char **inmask,char **outmask, presubdata *presubs,int npresub,size_t maxmem) { int i,j,k,l,p,sx,sy,ny,py,cny,nreal,nz,cz; double **lines; char ***linemasks,**wmask; presubdata *wp; fitsimage *img; sx=outimg->i.sx, sy=outimg->i.sy; for ( i=0,wp=presubs ; iimg==NULL || wp->img->data==NULL || wp->img->sx != sx || wp->img->sy != sy ) npresub=i; } nreal=0; for ( j=0 ; ji; if ( img->dim==2 ) nreal++; else nreal+=img->naxis[2]; } if ( maxmem>0 ) ny=(int)(maxmem/(sizeof(double)*(size_t)sx*nreal)); else ny=(sizeof(double)*sy)/nreal; /* fprintf(stderr,"maxmem=%d nreal=%d ny=%d\n",(int)(maxmem/1048576),nreal,ny); */ if ( ny<=0 ) ny=1; if ( ny>=sy ) ny=sy; lines=(double **)tensor_alloc_2d(double,sx,nreal); linemasks=(char ***)tensor_alloc_3d(char,sx,ny,nreal); wmask=(char **)tensor_alloc_2d(char,nreal,sx); py=-1,cny=0; for ( i=0 ; isy ) cny=sy-py; cz=0; for ( j=0 ; ji; if ( img->dim==2 ) nz=1; else nz=img->naxis[2]; for ( l=0 ; lheader,sx,sy,py,cny,NULL); } cz+=nz; } } cz=0; for ( j=0 ; ji; if ( img->dim==2 ) nz=1; else nz=img->naxis[2]; /* currently read image lines must be rescaled... */ if ( img->vdata == NULL ) { fits_read_image_line(inputs[j].fr,sx,img->bit,lines[cz]); for ( k=0 ; kcurr.bscale+img->curr.bzero; wmask[k][cz]=linemasks[cz][i-py][k]; } } /* pre-read images are assumed to have been rescaled! */ else if ( img->dim==2 ) { for ( k=0 ; kdata[i][k]; wmask[k][cz]=linemasks[cz][i-py][k]; } } else /* assuming dim == 3 ... ?! */ { double ***zdata; zdata=(double ***)img->vdata; for ( l=0 ; limg->data[i][k]*wp->scale; } } } if ( inmask != NULL ) { for ( k=0 ; ki.data[i],cp,wmask,outmask[i]); else combine_lines(lines,nreal,sx,outimg->i.data[i],cp,wmask,NULL); if ( py+cny>=i+1 ) py=-1; } tensor_free(wmask); tensor_free(linemasks); tensor_free(lines); return(0); } int combine_images_from_files_v2(comimg *inputs,int n,fits *outimg, compar *cp,char **inmask,char **outmask, presubdata *presubs,int npresub,size_t maxmem) { int i,j,k,l,p,sx,sy,ny,nreal,nz,cz,y0,dy; double ***clines; char ***cmasks,**wmask; presubdata *wp; fitsimage *img; sx=outimg->i.sx, sy=outimg->i.sy; for ( i=0,wp=presubs ; iimg==NULL || wp->img->data==NULL || wp->img->sx != sx || wp->img->sy != sy ) npresub=i; } nreal=0; for ( j=0 ; ji; if ( img->dim==2 ) nreal++; else nreal+=img->naxis[2]; } if ( maxmem>0 ) ny=(int)(maxmem/((sizeof(double)+1)*(size_t)sx*nreal)); else ny=sy/nreal; /* fprintf(stderr,"maxmem=%d nreal=%d ny=%d\n",(int)(maxmem/1048576),nreal,ny); */ if ( ny<=0 ) ny=1; if ( ny>=sy ) ny=sy; clines=(double ***)tensor_alloc_3d(double,sx,nreal,ny); cmasks=(char *** )tensor_alloc_3d(char ,sx,ny,nreal); wmask =(char ** )tensor_alloc_2d(char ,nreal,sx); for ( y0=0 ; y0ny ) dy=ny; cz=0; for ( j=0 ; ji; if ( img->dim==2 ) nz=1; else nz=img->naxis[2]; for ( l=0 ; lheader,sx,sy,y0,dy,NULL); } cz+=nz; } cz=0; for ( j=0 ; ji; if ( img->dim==2 ) nz=1; else nz=img->naxis[2]; if ( img->vdata==NULL ) { for ( k=0 ; kbit,clines[k][cz]); if ( img->curr.bscale != 1.0 || img->curr.bzero != 0.0 ) { for ( l=0 ; lcurr.bscale+img->curr.bzero; } } } } else if ( img->dim==2 ) { for ( k=0 ; kdata[y0+k],sx*sizeof(double)); } } else { double ***zdata; zdata=(double ***)img->vdata; for ( l=0 ; limg->data[y0+k][l]*wp->scale; } } } } for ( k=0 ; ki.data[y0+k],cp,wmask,outmask[y0+k]); else combine_lines(clines[k],nreal,sx,outimg->i.data[y0+k],cp,wmask,NULL); } y0+=dy; } tensor_free(wmask); tensor_free(cmasks); tensor_free(clines); return(0); } int combine_images_from_files(comimg *inputs,int n,fits *outimg, compar *cp,char **inmask,char **outmask, presubdata *presubs,int npresub,size_t maxmem) { int r; r=combine_images_from_files_v2(inputs,n,outimg,cp,inmask,outmask,presubs,npresub,maxmem); return(r); } /*****************************************************************************/ int combine_cleanup(comimg *inputs,int ninput) { int i; comimg *ci; for ( i=ninput-1 ; i>=0 ; i-- ) { ci=&inputs[i]; if ( ci->fr != NULL ) fclose(ci->fr); if ( ci->img != NULL ) fits_free(ci->img); } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/cache.h0000644000175000017500000001257412117334622013270 0ustar apalapal/*****************************************************************************/ /* cache.c */ /*****************************************************************************/ #ifndef __CACHE_H_INCLUDED #define __CACHE_H_INCLUDED 1 #include /* definition of type off_t */ /*****************************************************************************/ typedef struct cacheblock cacheblock; struct cacheblock { char *cachearray; off_t offset; int size; int nnch; cacheblock *prev; cacheblock *next; }; typedef struct { int fh; /* file handle */ int is_write; /* writeable cache */ int recordsize; off_t recordcount; int pagesize; /* see getpagesize() */ int chpagesize; /* LCM of pagesize and recordsize */ int chnrecord; /* chpagesize / recordsize */ /* = num of record in a cache block */ int tcblock; /* total cache blocks */ cacheblock *chblocks; int nchblock, /* should be less than 32k */ nusedblock, nmapped; short *nn_lookup; /* lookup table for cache blocks, */ /* this array has 'tcblock' elements */ cacheblock *recent; cacheblock *oldest; } cache; /*****************************************************************************/ #define CACHE_READONLY (0) /* ro - cache */ #define CACHE_READ_AND_WRITE (1) /* rw - cache */ /* cache_blocksize(): Returns the size of the smallest cache block, which is the least common multiple of recordsize and the architecture's preferred pagesize (reported by the getpagesize() system call). */ int cache_blocksize(int recordsize); /* cache_tcblock(): calculates the required value of 'tcblock' which is enough to hold all data in the cache at the same time (if it is passed to cache_init() as the value of 'nchblock' (see cache_init() for more details). */ int cache_tcblock(int recordsize,off_t recordcount,int multip); /* cache_init(): Initializes the cache 'ch' on the opened file descriptor 'fh'. The number of 'recordcount' objects (each with the size of 'recordsize') are assumed to be stored in the file. If we want to write into the file (using caching), set 'is_write' to a non-zero value (or CACHE_READ_AND_WRITE), otherwise set it to zero (or CACHE_READONLY). The caching will be done in 'nchblock' cache blocks, each block will have the size of 'multip' times the least common multiple of recordsize and the architecture's preferred pagesize (reported by the getpagesize() system call). The total count of cache blocks which will be used can be figured out using cache_tcblock(). If 'nchblock' is less than or equal to this value, all data can be cached into memory. Note that 'nchblock' cannot exceed 32k-1 (32767). If all data wants to be cached, increase 'multip' to have a tcblock count less than 32k. Note also that the maximum number of 'recordcount' is also architecture and/or compile-time dependent. If "off_t" is a 32-bit integer (sizeof(off_t) is 4), then the maximum number of objects is 2G, if "off_t" is a 64-bit integer (sizeof(off_t) is 8), then the maximum number of objects is 8E. The implementation of "off_t" depends on the architecture and can be tuned during compilation time using -D_FILE_OFFSET_BITS={32|64}. Be careful, because of even on modern unixes and 64-bit architectures(!), the default "off_t" type can either be a 32-bit integer. This library not uses the type of "long long", therefore it is fully ANSI-compatible and pedantic. */ int cache_init(cache *ch,int recordsize,off_t recordcount, int multip,int nchblock,int fh,int is_write); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* cache_read_record(): Returns a pointer to the 'recnum'th record using the cache 'ch'. Simple. The only important thing is that the subsequent calls of cache_read_record() may overwrite the internal buffers and the pointers previously returned by this call will have an unexpected contain. Because of the implementation, these contains are assured to be preserved if the total number of subsequent calls (including cache_write_record()'s also) is less than or equal to 'nchblock' (see cache_init() above). */ void * cache_read_record(cache *ch,off_t recnum); /* cache_write_record(): Stores the record 'record' in the cache 'ch' at the 'recnum'th record. */ int cache_write_record(cache *ch,off_t recnum,void *record); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* cache_sort_block(): Sorts the first 'n' record in the cache 'ch', from the offset 'o'. Note that o+n cannot be larger than ch->recordcount. */ int cache_sort_block(cache *ch,off_t o,off_t n, int (*compare)(const void *,const void *)); /* cache_sort(): Sorts the contents of the cache, using the function 'compare' for comparison. */ int cache_sort(cache *ch,int (*compare)(const void *,const void *)); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* cache_finalize(): Flushes and releases all cache data in 'ch'. The underlying file won't be closed by this call. */ int cache_finalize(cache *ch); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/psf.h0000644000175000017500000000475410667340127013023 0ustar apalapal/*****************************************************************************/ /* psf.h */ /*****************************************************************************/ #ifndef __PSF_H_INCLUDED #define __PSF_H_INCLUDED 1 /*****************************************************************************/ /* This structure describes a point-spread function (PSF) in a _tabulated_ */ /* way, including spatial variations. The half-size of the PSF stamp is */ /* 'hsize', each pixel has 'grid' times 'grid' equilateral subpixels while */ /* the order of the spatial variation is 'order' (it means polynomial order).*/ /* Therefore, the whole data describing this spatially vairating tabulated */ /* PSF requires (2*hsize+1) x (2*hsize+1) x ((order+1)*(order+2)/2) numbers */ /* which are stored in 'coeff'. During the polynomial evaluation of the */ /* tabulated data, the parameters 'ox', 'oy' and 'scale' are also used */ /* (see the appropriate functions in ./math/poly.c, e.g. eval_2d_poly()). */ typedef struct { int hsize; /* FITS header: 'PSFHSIZE' */ int grid; /* 'PSFSGRID' */ int order; /* 'PSFORDER' */ double ox, /* 'PSFOFFSX' */ oy, /* 'PSFOFFSY' */ scale; /* 'PSFSCALE' */ double ***coeff; /* NAXIS=3, [NX3][NX2][NX1] */ /* NAXIS1=grid*(2*hsize+1) */ /* NAXIS2=grid*(2*hsize+1) */ /* NAXIS3=(order+1)*(order+2)/2 */ } psf; /* The whole tabulated PSF can be stored as a three-dimensional FITS image */ /* also. The paremeters 'hsize', 'grid', 'order', 'ox', 'oy' and 'scale' are */ /* stored as special mandatory keywords, while the coefficients 'coeff' are */ /* stored in the primary image array. Altough some of the parameters can be */ /* calculated directly from FITS header values, the presence of _all_ of */ /* these headers are required. */ /*****************************************************************************/ #ifndef __IPOINT_STRUCT_DEFINED /* this one also can be defined in */ #define __IPOINT_STRUCT_DEFINED /* "stars.h", however, this library */ typedef struct /* is independent from 'stars.a'. */ { int x; int y; } ipoint; #endif typedef struct { ipoint *ipoints; double *yvals; int nipoint; double bg,amp; double cx,cy; } psfcandidate; /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/ui.c0000644000175000017500000001341312771627305012637 0ustar apalapal/*****************************************************************************/ /* ui.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (Very) high-level user-interface stuff for the programs of the 'fi' pkg. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2004-2009; Pal, A. (apal@szofi.net) */ /*****************************************************************************/ #include #include #include #include #include #include #include "fitsh.h" #include "longhelp.h" #include "io/scanarg.h" /*****************************************************************************/ char *get_progname(char *a0) { char *progname,*rbuff; progname=a0; rbuff=strrchr(progname,'/'); if ( rbuff != NULL ) progname=rbuff+1; return(progname); } int fprint_generic_version(FILE *fw,char *arg0,char *name,char *pv,int type) { if ( name==NULL && arg0==NULL ) name=NULL; else if ( name==NULL ) name=get_progname(arg0); if ( name==NULL ) name="(?)"; switch ( type ) { case -1: fprintf(fw,"%s %s (%s@%s)\n",name,pv,FITSH_VERSION,FITSH_RELEASE_DATE); fprintf(fw,"Copyright (C) 1996, 2002, 2004-2008, 2010-2015; %s <%s>\n",FITSH_MAINT_RNAME,FITSH_MAINT_EMAIL); break; case -2: fprintf(fw,"%s-%s [fitsh-%s]\n",name,pv,FITSH_VERSION); break; } return(0); } int fprint_generic_long_help(FILE *fw,int is_wiki,longhelp_entry *help,char *synopsis,char *description) { if ( is_wiki ) { fprintf(fw,"=== Synopsis ===\n"); fprintf(fw,": %s\n\n",synopsis); fprintf(fw,"=== Description ===\n"); fprintf(fw,": %s\n\n",description); } else { fprintf(fw,"Usage:\t%s\n",synopsis); fprintf(fw,"%s\n",description); fprintf(fw,"\n"); } if ( is_wiki ) longhelp_fprint_mediawiki(fw,help); else { longhelp_fprint(fw,help,0,-1); fprintf(fw,"\n"); fprintf(fw,"Report bugs to <%s>, see also http://fitsh.net/.\n",FITSH_MAINT_EMAIL); } return(0); } /*****************************************************************************/ int logmsg(int flag,char *msg,...) { va_list ap; FILE *fp; if ( flag ) { fp=stderr; va_start(ap,msg); vfprintf(fp,msg,ap); va_end(ap); fflush(fp); return(0); } else return(1); } /*****************************************************************************/ int parse_mask_flags(char *par) { int retflag; retflag=scanflag(par,SCANFLAG_ALLOW_NEGATE|SCANFLAG_ALLOW_RESET, "none", MASK_OK, "clear", MASK_CLEAR, "fault", MASK_FAULT, "hot", MASK_HOT, "cosmic", MASK_COSMIC, "outer", MASK_OUTER, "oversaturated",MASK_OVERSATURATED, "leaked", MASK_LEAKED, "bloomed", MASK_LEAKED, "saturated", MASK_SATURATED, "interpolated", MASK_INTERPOLATED, "all", MASK_ALL, "bad", MASK_BAD, NULL); if ( retflag<0 ) return(-1); else return( retflag & MASK_ALL ); } int parse_fits_data_param(char *par,fitsdataparam *fdp) { int i,b,type; if ( par==NULL ) return(0); fdp->nquantizebit=0; type=-1; i=scanpar(par,SCANPAR_DEFAULT, "bscale:%g%f",&fdp->bscale,&fdp->is_scale, "bzero:%g%f",&fdp->bzero,&fdp->is_scale, "bitpix:%d",&fdp->bitpix, "char:%SN0f",&type, "byte|unsignedchar|unsigned_char:%SN1f",&type, "int|short:%SN2f",&type, "word|unsigned|unsignedint|unsigned_int|unsignedshort|unsigned_short:%SN3f",&type, "long:%SN4f",&type, "dword|unsignedlong|unsigned_long:%SN5f",&type, "float:%SN6f",&type, "double:%SN7f",&type, "quantizebits:%d",&fdp->nquantizebit, NULL); if ( i ) return(1); switch ( type ) { case 0: fdp->bitpix= 8;fdp->bscale=1.0;fdp->bzero=0.0; break; case 1: fdp->bitpix= 8;fdp->bscale=1.0;fdp->bzero=-(double)(1<<( 8-1)); break; case 2: fdp->bitpix= 16;fdp->bscale=1.0;fdp->bzero=0.0; break; case 3: fdp->bitpix= 16;fdp->bscale=1.0;fdp->bzero=-(double)(1<<(16-1)); break; case 4: fdp->bitpix= 32;fdp->bscale=1.0;fdp->bzero=0.0; break; case 5: fdp->bitpix= 32;fdp->bscale=1.0;fdp->bzero=-(double)(1<<(32-1)); break; case 6: fdp->bitpix=-32;fdp->bscale=1.0;fdp->bzero=0.0; break; case 7: fdp->bitpix=-64;fdp->bscale=1.0;fdp->bzero=0.0; break; } if ( type>=0 ) fdp->is_scale=1; b=fdp->bitpix; if ( b && ! ( b==8 || b==16 || b==32 || b==-32 || b==-64 ) ) return(1); return(0); } /*****************************************************************************/ static char nasty_chars[]="()*?[]&|;"; int is_nasty_char(int t) { if ( strchr(nasty_chars,t)==NULL ) return(0); else return(1); } int is_any_nasty_char(char *buff) { while ( *buff ) { if ( is_nasty_char(*buff) ) return(1); buff++; } return(0); } /*****************************************************************************/ size_t parse_max_memory_string(char *maxmemstr) { size_t maxmem; if ( maxmemstr != NULL ) { double mxd; int len,t; size_t pagesize; if ( sscanf(maxmemstr,"%lg",&mxd)<1 ) return(1); /* unexpected */ len=strlen(maxmemstr); if ( len>0 ) t=maxmemstr[len-1]; else t=-1; if ( t=='b' || t=='B' ) { if ( len>1 ) t=maxmemstr[len-2]; else t=-1; } if ( t=='k' || t=='K' ) mxd*=1024.0; else if ( t=='m' || t=='M' ) mxd*=1024.0*1024.0; else if ( t=='g' || t=='G' ) mxd*=1024.0*1024.0*1024.0; else if ( t=='t' || t=='T' ) mxd*=1024.0*1024.0*1024.0*1024.0; else return(1); /* unexpected */ if ( sizeof(size_t)<=4 && mxd>=1920.0*1024.0*1024.0 ) mxd=1920.0*1024.0*1024.0; /* 32bit: 1.875 giga */ else if ( mxd>=1024*1024.0*1024.0*1024.0*1024.0 ) mxd=1024*1024.0*1024.0*1024.0*1024.0; /* 64bit: 1.000 peta */ maxmem=(size_t)mxd; #ifdef HOST_WIN32 pagesize=4096; #else pagesize=(size_t)getpagesize(); #endif if ( maxmem<=pagesize ) maxmem=pagesize; maxmem=(maxmem)&(~(pagesize-1)); } else maxmem=0; return(maxmem); } /*****************************************************************************/ fitsh-0.9.2/src/star-cand-biq.c0000644000175000017500000001157712771247642014662 0ustar apalapal/*****************************************************************************/ /* star-cand-biq.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* An extension to stars.c, used by `fistar` to search stars or star */ /* candidates on images... based on the method of biquadratic surfaces. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2005, Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include "fitsmask.h" #include "math/spline/biquad.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "io/iof.h" #include "tensor.h" #include "fitsh.h" #include "common.h" #include "stars.h" /*****************************************************************************/ #define NUM_ITER 6 /*****************************************************************************/ static int biquad_poly_coefficients(double **cf,double *pcf) { double wa1,wa2,wb1,wb2; pcf[0]=cf[0][0]; pcf[1]=-4.0*cf[0][0]+6.0*cf[0][1]-2.0*cf[0][2]; wa1 =-4.0*cf[1][0]+6.0*cf[1][1]-2.0*cf[1][2]; wa2 =-4.0*cf[2][0]+6.0*cf[2][1]-2.0*cf[2][2]; pcf[2]=3.0*(cf[0][0]-2.0*cf[0][1]+cf[0][2]); wb1 =3.0*(cf[1][0]-2.0*cf[1][1]+cf[1][2]); wb2 =3.0*(cf[2][0]-2.0*cf[2][1]+cf[2][2]); pcf[3]=-4.0*cf[0][0]+6.0*cf[1][0]-2.0*cf[2][0]; pcf[4]=-4.0*pcf[1]+6.0*wa1-2.0*wa2; pcf[5]=-4.0*pcf[2]+6.0*wb1-2.0*wb2; pcf[6]=3.0*(cf[0][0]-2.0*cf[1][0]+cf[2][0]); pcf[7]=3.0*(pcf[1]-2.0*wa1+wa2); pcf[8]=3.0*(pcf[2]-2.0*wb1+wb2); return(0); } static int biquad_poly_coeff_rearrange(double *pcf,double x,double y,double *out) { double ncf[9]; int i; ncf[0]=pcf[0]+x*(pcf[1]+pcf[2]*x)+y*((pcf[3]+x*(pcf[4]+pcf[5]*x))+y* (pcf[6]+x*(pcf[7]+pcf[8]*x))); ncf[1]=pcf[1]+2*pcf[2]*x+y*((pcf[4]+2*pcf[5]*x)+y*(pcf[7]+2*pcf[8]*x)); ncf[2]=pcf[2]+y*(pcf[5]+y*pcf[8]); ncf[3]=pcf[3]+2*pcf[6]*y+x*((pcf[4]+2*pcf[7]*y)+x*(pcf[5]+2*pcf[8]*y)); ncf[4]=pcf[4]+2*pcf[5]*x+2*y*(pcf[7]+2*pcf[8]*x); ncf[5]=pcf[5]+2*pcf[8]*y; ncf[6]=pcf[6]+x*(pcf[7]+x*pcf[8]); ncf[7]=pcf[7]+2*pcf[8]*x; ncf[8]=pcf[8]; for ( i=0 ; i<9 ; i++ ) { out[i]=ncf[i]; } return(0); } /*****************************************************************************/ int search_star_candidates_biquad(fitsimage *img,char **mask,candidate **rcands,int *rncand,range *srcrange) { double **bqc,*bql[3],xd,xu,yl,yr,det,x,y,pcf[9],x0,y0,peak; int sx,sy,i,j,k; candidate *cands,*wc; int ncand; if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); bqc=(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); biquad_coeff(img->data,sx,sy,bqc,mask); cands=NULL; ncand=0; for ( i=0 ; i=1.0 || y0>=1.0 ) continue; /*fprintf(stderr,"-> (%12g %12g)\n",x0,y0);*/ x=x0,x0+=(double)j; y=y0,y0+=(double)i; peak=biquad_eval(bql,x,y); cands=(candidate *)realloc(cands,sizeof(candidate)*(ncand+1)); wc=&cands[ncand]; wc->ix=j,wc->iy=i; wc->cx=x0, wc->cy=y0; wc->peak=peak; wc->sxx=wc->syy=wc->sxy=0.0; wc->marked=0; wc->ipoints=NULL; wc->nipoint=0; ncand++; } } tensor_free(bqc); if ( rcands != NULL ) *rcands=cands; if ( rncand != NULL ) *rncand=ncand; return(0); } fitsh-0.9.2/src/pselect.c0000644000175000017500000001044211116253273013647 0ustar apalapal/*****************************************************************************/ /* pselect.c [-> point.h, sort.c] */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* A library for selecting points homogenously from a given set. */ /* This library is not standalone, it requires the declaration of the */ /* structure 'point' defined in point.h and some functions from sort.c. */ /* (c) 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in pselect.h */ /*****************************************************************************/ #include #include #include #include #include "math/point.h" #include "index/sort.h" #include "pselect.h" /*****************************************************************************/ static int point_select_count(point *points,int npoint,double x0,double y0, double x1,double y1,char *ret,int val) { int n; n=0; if ( val<0 || ret==NULL ) { while ( npoint ) { if ( x0 <= points->x && points->x < x1 && y0 <= points->y && points->y < y1 ) n++; npoint--,points++; }; } else { while ( npoint ) { if ( x0 <= points->x && points->x < x1 && y0 <= points->y && points->y < y1 ) n++,*ret=val; npoint--,points++,ret++; }; } return(n); } static int point_select_num(point *points,int npoint,double x0,double y0, double x1,double y1,char *ret,int val,int nn) { int n; if ( val<0 || ret==NULL || nn<0 ) return(0); n=0; while ( npoint && nn>0 ) { if ( x0 <= points->x && points->x < x1 && y0 <= points->y && points->y < y1 ) n++,nn--,*ret=val; npoint--,points++,ret++; }; return(n); } static int point_select_compare(int i1,int i2,void *param) { point *points; points=(point *)param; if ( points[i1].weight < points[i2].weight ) return(1); else if ( points[i1].weight == points[i2].weight ) return(0); else return(-1); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int point_select(point *points,int npoint,char *ret,int nselect, double x0,double y0,double x1,double y1,int level) { double xl,xm,xh, yl,ym,yh,w; int i,k,n,npp; int n_bl,n_br,n_tl,n_tr, s_bl,s_br,s_tl,s_tr; if ( nselect==0 ) return(0); if ( x0>x1 ) w=x0,x0=x1,x1=w; if ( y0>y1 ) w=y0,y0=y1,y1=w; npp=0; if ( level==0 ) { int *index; n=point_select_count(points,npoint,x0,y0,x1,y1,ret,2); if ( nselect>=n ) { for ( i=0 ; i #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "fitsmask.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "io/format.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "fbase.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "math/spline/bicubic.h" #include "math/spline/spline.h" #include "statistics.h" #include "transform.h" #include "tensor.h" #include "common.h" #include "weight.h" #include "history.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ #define TRANS_INTERPOLATE 0x00 #define TRANS_INTEGRATE 0x01 #define TRANS_STEPLIKE 0x00 #define TRANS_SPLINE 0x02 /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ #define SMOOTH_NONE 0 #define SMOOTH_SPLINE 1 #define SMOOTH_POLYNOMIAL 2 #define SMOOTH_PREFILTER_NONE 0 #define SMOOTH_PREFILTER_MEAN 1 #define SMOOTH_PREFILTER_MEDIAN 2 typedef struct { int type; /* see SMOOTH_* */ int xorder,yorder; /* polynomial and/or spoine order */ int filter; /* see SMOOTH_PREFILTER_* */ int fxhsize,fyhsize; /* filter blocx x/y half size */ double frejratio; /* filter rejection level ratio (<1) */ int niter; /* number of iterations */ double lower,upper; /* rejection level in sigma */ int is_mean_unity; /* scale result to have unity mean */ int is_detrend; /* detrend image instead of smoothing*/ } smooth; /*****************************************************************************/ int min4(int a,int b,int c,int d) { if ( ba ) a=b; if ( c>a ) a=c; if ( d>a ) a=d; return(a); } /*****************************************************************************/ int fprint_fitrans_usage(FILE *fw) { fprintf(fw, "Usage:\tfitrans [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[[-i|--input] [] [--frame ] [-M|--input-mask ]]\n" "\t[-C|--comment] [-V|--verbose] [-o|--output ]\n"); fprintf(fw, "General (analytical) transformation:\n" "\t[-T |-t [-m|-l|-c|-k] [--reverse]] \n" "Layer extraction or slicing data cubeimages into disctint layers:\n" "\t[-y|--layer ]\n" "\t[-x|--explode [-y|--first-layer ]]\n"); fprintf(fw, "Zooming/shrinking, shifting:\n" "\t[-z|--zoom ] [-g|--magnify ]\n" "\t[-r|--shrink [-d|--median] [--optimistic-masking]]\n" "\t[-e|--shift ,]\n"); fprintf(fw, "Noise estimation:\n" "\t[-n|--noise]\n"); fprintf(fw, "Large scale smoothing:\n" "\t[-a|--smooth {spline|polynomial},[xy]order=,[unity],[detrend]\n" "\t\t[mean|median],[xy]hsize=,[rejection=],\n" "\t\t[iterations=],[lower|upper|sigma=]]\n"); fprintf(fw, "Other optional parameters (override the default size/depth/offset values):\n" "\t[-s|--size [-],[-] [--flip-[x][y]]] [-f|--offset ,]\n" "\t[-b|--bitpix ]\n" "\t[-D|--data bitpix=,bscale=,bzero=|]\n"); return(0); } longhelp_entry fitrans_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-i, --input ", "Name of the input FITS image file." }, { "-o, --output ", "Name of the output FITS image file." }, { "-b, --bitpix ", "Standard FITS output bitpix value." }, { "-D, --data ", "Output pixel data format specification." }, { "Spatial transformations:", NULL }, { "-T, --input-transformation ", "Name of the file which contains the transformation description." "Such a file can be created e.g. by the programs `grtrans` or `grmatch`. " "This file contains basically the same set of = " "pairs as it is used after the -t|--transformation option (see there)." }, { "-t, --transformation ", "Comma-separated list of parameters for the spatial transformation, " "see section \"Parameters for spatial transformations\" below." }, { "-e, --shift ,", "Imply a transformation that shifts the image by ,." }, { "--reverse, --inverse", "Apply the inverse transformation to the image rather than the " "original one. " }, { "-m", "Simple linear interpolation between pixels, with no exact flux " "conservation (just a multiplication by the Jacobian of " "the transformation)." }, { "-l", "Linear interpolation between the pixels involving exact flux " "conservation by integrating on the image surface." }, { "-c", "Bicubic spline interpolation between pixels, with no exact flux " "conservation (just a multiplication by the Jacobian of " "the transformation)." }, { "-k", "Interpolation by integrationg the flux on a biquadratic interpolation " "surface, yielding exact flux conservation. " }, { "-s, --size ,", "The size of the output image if it should differ from the original " "image size." }, { "-f, --offset ,", "Zero-point coordinate of the output image in the input image. " }, { "Parameters for spatial transformations:", NULL }, { "type=", "Type of the transformation. In the actual implementation, the " "only supported type for a transformation is \"polynomial\". " }, { "order=", "Polynomial order for the transformation." }, { "dxfit=", "Comma-separated list of the polynomial coefficients for the " "X coordinate. The number of coefficients must be 1, 3, 6, ... for " "the orders 0, 1, 2, ... respectively." }, { "dyfit=", "Comma-separated list of the polynomial coefficients for the " "Y coordinate." }, { "Other simple spatial geometric transformations:", NULL }, { "-z, --zoom ", "Zoom the image by the given (integer) factor, involving a biquadratic " "subpixel-level interpolation and therefore exact flux conservation. " }, { "-r, --shrink ", "Shrink the image by the given (integer) factor. " }, { "-d, --median", "Use a median-based averaging during the shrinking operation. " }, { "--optimistic-masking", "Imply some optimism during the shrinking operation: masked pixels " "are ignored during the averaging process and the final mask will " "be computed in a complement manner. " }, { "-g, --magnify ", "Same as zooming the image but there is no subpixel-level interpolation." }, { "Large-scale image smoothing:", NULL }, { "-a, --smooth ", "Perform a smoothing on the image. The parameters of the smoothing " "are the following:" }, { "spline", "Do a spline interpolation smoothing" }, { "polynomial", "Do a polynomial interpolation smoothing" }, { "[xy]order=", "Spatial order of the smoothing function. The order in the X and Y " "coordinates can be set independently, by setting \"xorder=...\" or " "\"yorder=...\"." }, { "unity", "Scale the resulting smoothed image to have a mean of 1." }, { "detrend", "The resulting image will be the original image divided by the " "best fit smoothed surface." }, { "[xy]hsize=", "Do a box filtering with the given halfsize." }, { "mean", "Use the mean value of the pixels for the box filtering." }, { "median", "Use the median value of the pixels for the box filtering." }, { "iterations=", "Number of iterations to reject outlier pixels from the box." }, { "lower, upper, sigma=", "Lower, upper or symmetric rejection level in the units of " "standard deviation." }, { "Noise estimation:", NULL }, { "-n, --noise", "Derive an image which reflects the \"noise level\" of the image. " }, { "Slicing or exploding data cube images:", NULL }, { "-y, --layer ", "Layer (z-axis index) of the desired image slice." }, { "-x, --explode ", "Explode the input image into individual planar (two dimensional) " "FITS image. The basename must contain at least one printf-like " "tag of %d, %i, %o, %x or %X that is replaced by the appropriate " "layer number index. " }, { "-y, --first-layer ", "Use the specified value for the first layer index. The subsequent " "layer indices are incremented normally. By default, the index of " "the first data cube layer is 0. " }, { NULL, NULL } }; int fprint_fitrans_long_help(FILE *fw,int is_wiki) { char *synopsis= "fitrans [transformation and options] [-o|--output ]"; char *description= "The main purpose of this program is to perform specific or generic " "geometric transformations on the input image."; fprint_generic_long_help(fw,is_wiki,fitrans_long_help,synopsis,description); return(0); } /*****************************************************************************/ /* prefilter_image(): Do a moving block filtering on the data matrix 'data' (with the respecive size of 'sx' by 'sy') optionally taking in to account the mask 'mask' marking the bad and/or unexpected points. The resulted block filtered image is then stored in 'fltd' (with the same size) and the appropriate mask is stored in 'fmsk' (if it is not NULL). The following smooth parameters are used from the object 'sp': sp->filter (see SMOOTH_PREFILTER_* definitions) sp->f[xy]hsize (block halfsizes, both 0 means do nothing) sp->frejratio (rejection ratio if SMOOTH_PREFILTER_MEAN is used) */ typedef struct { int x,y; double val; } ppixel; static int ppixel_compare(const void *v1,const void *v2) { ppixel *p1=(ppixel *)v1; ppixel *p2=(ppixel *)v2; if ( p1->val < p2->val ) return(-1); else return(1); } int ppixel_sort(ppixel *pps,int npp) { if ( pps != NULL && npp>0 ) qsort(pps,npp,sizeof(ppixel),ppixel_compare); return(0); } int prefilter_image(double **data,int sx,int sy,double **fltd, smooth *sp,char **mask,char **fmsk) { int hx,hy; int i,j,k,l,k0,k1; ppixel *pps,*ppt,*ppw,*ppn,**apr; double sumpp; int npp,tpp,nnp; int *ran; if ( data==NULL || fltd==NULL ) return(-1); if ( ! sp->filter || (sp->fxhsize <= 0 && sp->fyhsize <= 0) ) { for ( i=0 ; ifxhsize; hy=sp->fyhsize; pps=(ppixel *)malloc(sizeof(ppixel)*(2*hx+1)*(2*hy+1)); ppt=(ppixel *)malloc(sizeof(ppixel)*(2*hx+1)*(2*hy+1)); ppn=(ppixel *)malloc(sizeof(ppixel)*(2*hy+1)); apr=(ppixel **)tensor_alloc_2d(ppixel,2*hy+1,sx); ran=(int *)malloc(sizeof(int)*sx); for ( j=0 ; j=sy ) k1=sy-1-i; for ( k=k0 ; k<=k1 ; k++ ) { for ( l=0 ; l<=hx && l0 ) { if ( sp->filter==SMOOTH_PREFILTER_MEDIAN ) { fltd[i][j]=0.5*(pps[(npp-1)/2].val+pps[(npp)/2].val); } else if ( sp->filter==SMOOTH_PREFILTER_MEAN && sp->frejratio<=0.0 ) { fltd[i][j]=sumpp/npp; } else if ( sp->filter==SMOOTH_PREFILTER_MEAN ) { int k,l0,l1; l0=(int)((double)npp*(sp->frejratio/2.0)); l1=npp-l0; fltd[i][j]=0.0; for ( k=l0 ; kl0 ) fltd[i][j]/=(double)(l1-l0); else { fltd[i][j]=0.0; fmsk[i][j]=MASK_FAULT; } } else /* unimplemented mode: */ { fltd[i][j]=0.0; fmsk[i][j]=MASK_FAULT; } } else { fltd[i][j]=0.0; fmsk[i][j]=MASK_FAULT; /* TBD: combination of masks */ } if ( ! (j j-hx ) { while ( l i-hy ) { while ( ltype (see SMOOTH_* definitions) sp->[xy]order (x and y spatial variation orders) sp->niter (sigma rejection iterations) sp->lower,upper (rejection level for outlyers) */ int smooth_image(double **data,int sx,int sy,double **fltd, smooth *sp,char **mask,char **omsk) { int xorder,yorder; double **fxbase,**fybase; double *fvars,*bvector,**amatrix,w,f; int nvar,nxvar,nyvar; char **tmsk; int i,j,iiter,k,l; if ( data==NULL || fltd==NULL ) return(-1); xorder=sp->xorder; yorder=sp->yorder; fxbase=(double **)tensor_alloc_2d(double,sx,xorder+1); fybase=(double **)tensor_alloc_2d(double,sy,yorder+1); if ( sp->type==SMOOTH_SPLINE ) { fbase_spline(fxbase,xorder,sx); fbase_spline(fybase,yorder,sy); } else if ( sp->type==SMOOTH_POLYNOMIAL ) { fbase_polynomial(fxbase,xorder,sx); fbase_polynomial(fybase,yorder,sy); } else { xorder=0; yorder=0; fbase_polynomial(fxbase,0,sx); fbase_polynomial(fybase,0,sy); } nxvar=xorder+1; nyvar=yorder+1; nvar=nxvar*nyvar; tmsk=(char **)tensor_alloc_2d(char,sx,sy); for ( i=0 ; initer>0?sp->niter:0) ; iiter++ ) { for ( k=0 ; kniter ) { double s2,sig; s2=0.0; for ( i=0 ; i0.0 ) sig=sqrt(s2); else break; for ( i=0 ; ilower || +sig*sp->upper < f ) tmsk[i][j]=1; } } } } for ( i=0 ; isx, sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); if ( out->sx != sx || out->sy != sy ) return(1); if ( sp->filter ) { data=(double **)tensor_alloc_2d(double,sx,sy); fmsk=(char **)tensor_alloc_2d(char,sx,sy); prefilter_image(img->data,sx,sy,data,sp,mask,fmsk); } else { data=img->data; fmsk=mask; } if ( sp->type ) smooth_image(data,sx,sy,out->data,sp,fmsk,omsk); else { int i,j; for ( i=0 ; idata[i][j]=data[i][j]; omsk[i][j]=fmsk[i][j]; } } } if ( sp->is_mean_unity ) { double s,n; int i,j; s=n=0.0; for ( i=0 ; idata[i][j]; } } if ( s>0.0 ) { s=n/s; for ( i=0 ; idata[i][j] *= s; } } } } else if ( sp->is_detrend ) { double s,n,d; int i,j; s=n=0.0; for ( i=0 ; idata[i][j]; } } s=s/n; for ( i=0 ; idata[i][j]; if ( d>0.0 ) out->data[i][j]=img->data[i][j]*s/d; else out->data[i][j]=0.0; } } } if ( sp->filter ) { tensor_free(fmsk); tensor_free(data); } return(0); } /*****************************************************************************/ int interpolate_image_linear(fitsimage *img,char **mask,double x,double y,double *ret) { int ix,iy,flag; double u,v; ix=(int)floor(x),iy=(int)floor(y); u=x-(double)ix,v=y-(double)iy; if ( x<0 || y<0 || ix>=img->sx-2 || iy>=img->sy-2 ) return(MASK_OUTER); if ( mask != NULL ) flag=mask[iy][ix]|mask[iy+1][ix+1]|mask[iy][ix+1]|mask[iy+1][ix]; else flag=0; *ret= img->data[iy+0][ix+0]*(1-u)*(1-v)+ img->data[iy+0][ix+1]*( +u)*(1-v)+ img->data[iy+1][ix+0]*(1-u)*( +v)+ img->data[iy+1][ix+1]*( +u)*( +v); return(flag); } int interpolate_image_bicubic(double **c,int sx,int sy,char **mask,double fx,double fy,double *ret) { int ix,iy,flag; ix=(int)floor(fx),iy=(int)floor(fy); if ( fx<0 || fy<0 || ix>=sx-2 || iy>=sy-2 ) return(MASK_OUTER); if ( mask != NULL ) flag=mask[iy][ix]|mask[iy+1][ix+1]|mask[iy][ix+1]|mask[iy+1][ix]; else flag=0; *ret=bicubic_inter(c,fx,fy); return(flag); } int apply_transformation_polynomial_interpolate (fitsimage *img,char **mask,fitsimage *outimg,char **outmask, int ofx,int ofy,transformation *tf,int is_spline,int is_invert) { int i,j,sx,sy,nsx,nsy,flag,order; double x,y,nx,ny,w,ox,oy,scale; double *jxx,*jxy,*jyx,*jyy,cjxx,cjxy,cjyx,cjyy,cj; double **splinecoeff; sx =img->sx ,sy =img->sy; nsx=outimg->sx,nsy=outimg->sy; ox=tf->ox,oy=tf->oy,scale=tf->scale; order=tf->order; if ( is_spline ) { splinecoeff=(double **)tensor_alloc_2d(double,2*sx,2*sy); if ( splinecoeff==NULL ) return(-1); logmsg(is_verbose,"Calculating spline coefficients... "); bicubic_coeff(img->data,sx,sy,splinecoeff,mask); logmsg(is_verbose,"done.\n"); } else splinecoeff=NULL; transformation_get_jacobi(tf,&jxx,&jxy,&jyx,&jyy); logmsg(is_verbose,"Transforming... "); for ( i=0 ; idata[i][j]=w*cj; else outmask[i][j]=flag,outimg->data[i][j]=0.0; } logmsg(is_verbose>=2,"\rTransforming... (%d/%d)... ",i+1,nsy); } logmsg(is_verbose,"done.\n"); if ( splinecoeff != NULL ) tensor_free(splinecoeff); if ( jyy != NULL ) free(jyy); if ( jyx != NULL ) free(jyx); if ( jxy != NULL ) free(jxy); if ( jxx != NULL ) free(jxx); return(0); } int apply_transformation_polynomial_integrate (fitsimage *img,char **mask,fitsimage *outimg,char **outmask,int ofx,int ofy, transformation *tf,int is_spline,int is_invert) { int i,j,sx,sy,nsx,nsy,flag; double x,y,nx,ny,dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4,w; double **bqc,**dxyline,*wd; double *jxx,*jxy,*jyx,*jyy; int idx1,idy1,idx2,idy2,idx3,idy3,idx4,idy4,idxl,idxh,idyl,idyh,ix,iy; sx =img->sx ,sy =img->sy; nsx=outimg->sx,nsy=outimg->sy; if ( is_spline ) { bqc=(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); if ( bqc==NULL ) return(-1); logmsg(is_verbose,"Calculating biquadratic spline coefficients... "); biquad_coeff(img->data,sx,sy,bqc,mask); logmsg(is_verbose,"done.\n"); } else bqc=NULL; if ( is_invert ) transformation_get_jacobi(tf,&jxx,&jxy,&jyx,&jyy); else jxx=jxy=jyx=jyy=NULL; logmsg(is_verbose,"Transforming... "); dxyline=(double **)tensor_alloc_2d(double,nsx+1,4); y=(double)(0-ofy); for ( j=0 ; j<=nsx ; j++ ) { x=(double)(j-ofx); if ( ! is_invert ) transformation_eval_normal_2d(x,y,tf,&nx,&ny); else transformation_eval_invert_2d(x,y,tf,&nx,&ny,jxx,jxy,jyx,jyy); dxyline[0][j]=nx, dxyline[1][j]=ny; } for ( i=0 ; i=sx || dy1>=sy || dx2>=sx || dy2>=sy ) flag|=MASK_OUTER; else if ( dx3>=sx || dy3>=sy || dx4>=sx || dy4>=sy ) flag|=MASK_OUTER; else if ( mask != NULL ) { idxl=min4(idx1,idx2,idx3,idx4); if ( idxl<0 ) flag|=MASK_OUTER,idxl=0; idxh=max4(idx1,idx2,idx3,idx4); if ( idxh>=sx ) flag|=MASK_OUTER,idxh=sx-1; idyl=min4(idy1,idy2,idy3,idy4); if ( idyl<0 ) flag|=MASK_OUTER,idyl=0; idyh=max4(idy1,idy2,idy3,idy4); if ( idyh>=sy ) flag|=MASK_OUTER,idyh=sy-1; for ( iy=idyl ; iy<=idyh ; iy++ ) { for ( ix=idxl ; ix<=idxh ; ix++ ) { flag |= mask[iy][ix]; } } } if ( ! flag ) { outmask[i][j]=0; if ( is_spline && bqc != NULL ) w=biquad_isc_int_triangle(bqc,1,dx1,dy1,dx2,dy2,dx3,dy3,sx,sy)+ biquad_isc_int_triangle(bqc,1,dx2,dy2,dx4,dy4,dx3,dy3,sx,sy); else w=biquad_isc_int_triangle(img->data,0,dx1,dy1,dx2,dy2,dx3,dy3,sx,sy)+ biquad_isc_int_triangle(img->data,0,dx2,dy2,dx4,dy4,dx3,dy3,sx,sy); outimg->data[i][j]=w; } else { outmask[i][j]=flag; outimg->data[i][j]=0.0; } } wd=dxyline[0],dxyline[0]=dxyline[2],dxyline[2]=wd; wd=dxyline[1],dxyline[1]=dxyline[3],dxyline[3]=wd; logmsg(is_verbose>=2,"\rTransforming... (%d/%d)... ",i+1,nsy); } logmsg(is_verbose,"done.\n"); if ( bqc != NULL ) tensor_free(bqc); if ( dxyline != NULL ) tensor_free(dxyline); if ( jyy != NULL ) free(jyy); if ( jyx != NULL ) free(jyx); if ( jxy != NULL ) free(jxy); if ( jxx != NULL ) free(jxx); return(0); } int apply_transformation (fitsimage *img,char **mask,fitsimage *outimg,char **outmask, int ofx,int ofy,transformation *tf,int int_method,int is_invert) { int r; if ( tf->type == 1 ) { if ( int_method & TRANS_INTEGRATE ) r=apply_transformation_polynomial_integrate(img,mask,outimg,outmask,ofx,ofy,tf,(int_method&TRANS_SPLINE),is_invert); else r=apply_transformation_polynomial_interpolate(img,mask,outimg,outmask,ofx,ofy,tf,(int_method&TRANS_SPLINE),is_invert); } else r=-1; return(r); } /*****************************************************************************/ int zoom_image (fitsimage *img,char **mask,fitsimage *outimg,char **outmask, int ofx,int ofy,int scale) { int sx,sy,nsx,nsy; int i,j,k,l,m,ii,jj; double **wret,**bqc; if ( img==NULL || outimg==NULL ) return(1); if ( mask==NULL || outmask==NULL ) return(1); sx=img->sx, sy=img->sy; nsx=outimg->sx; nsy=outimg->sy; if ( sx==0 || sy==0 || nsx==0 || nsy==0 ) return(0); wret=(double **)tensor_alloc_2d(double,scale,scale); bqc =(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); logmsg(is_verbose,"Calculating biquadratic coefficients... "); biquad_coeff(img->data,sx,sy,bqc,mask); logmsg(is_verbose,"done.\n"); logmsg(is_verbose==1,"Zooming... "); for ( i=0 ; isy-1 || jj>sx-1 ) { for ( k=0 ; kdata[i*scale+k][j*scale+l]=wret[k][l]; outmask[i*scale+k][j*scale+l]=m; } } } logmsg(is_verbose>=2,"\rZooming... (%d/%d)... ",i+1,nsy/scale); } logmsg(is_verbose,"done.\n"); tensor_free(bqc); tensor_free(wret); return(0); } int zoom_raw_image (fitsimage *img,char **mask,fitsimage *outimg,char **outmask, int ofx,int ofy,int scale) { int sx,sy,nsx,nsy; int i,j,k,l,m,ii,jj; double wr,sfactor; if ( img==NULL || outimg==NULL ) return(1); if ( mask==NULL || outmask==NULL ) return(1); sx=img->sx, sy=img->sy; nsx=outimg->sx; nsy=outimg->sy; if ( sx==0 || sy==0 || nsx==0 || nsy==0 ) return(0); sfactor=1.0/(double)(scale*scale); for ( i=0 ; isy-1 || jj>sx-1 ) { wr=0.0; m|=MASK_OUTER; } else if ( mask[ii][jj] ) { wr=0.0; m|=mask[ii][jj]; } else { wr=img->data[ii][jj]*sfactor; m=0; } for ( k=0 ; kdata[i*scale+k][j*scale+l]=wr; outmask[i*scale+k][j*scale+l]=m; } } } } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int shrink_image (fitsimage *img,char **mask,fitsimage *outimg,char **outmask, int ofx,int ofy,int scale,int do_median,int do_avg_mode) { int sx,sy,nsx,nsy; int i,j,k,l,ii,jj,m,t; double w,*medarr; if ( img==NULL || outimg==NULL ) return(1); if ( mask==NULL || outmask==NULL ) return(1); sx=img->sx, sy=img->sy; nsx=outimg->sx; nsy=outimg->sy; if ( sx==0 || sy==0 || nsx==0 || nsy==0 ) return(0); if ( do_median ) medarr=(double *)malloc(sizeof(double)*(scale*scale)); else medarr=NULL; for ( i=0 ; isy-scale || jj>sx-scale ) { outimg->data[i][j]=0.0; outmask[i][j]=MASK_OUTER; } else if ( medarr != NULL ) { m=0; if ( do_avg_mode==0 ) { for ( k=0,t=0 ; kdata[ii+k][jj+l]; t++; } } outmask[i][j]=m; outimg->data[i][j]=median(medarr,t)*(double)(scale*scale); } else if ( do_avg_mode==1 ) { for ( k=0,t=0 ; kdata[ii+k][jj+l]; t++; } } } outmask[i][j]=(~m)&MASK_ALL; outimg->data[i][j]=median(medarr,t)*(double)(scale*scale); } else { outmask[i][j]=MASK_ALL; outimg->data[i][j]=0.0; } } else { w=0.0;m=0; for ( k=0 ; kdata[ii+k][jj+l]; } } outmask[i][j]=m; outimg->data[i][j]=w; } } } if ( medarr != NULL ) free(medarr); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int scatter_image (fitsimage *img,char **mask,fitsimage *outimg,char **outmask) { int sx,sy,nsx,nsy; int i,j; double **bqc; if ( img==NULL || outimg==NULL ) return(1); if ( mask==NULL || outmask==NULL ) return(1); sx=img->sx, sy=img->sy; nsx=outimg->sx; nsy=outimg->sy; if ( sx==0 || sy==0 || nsx==0 || nsy==0 ) return(0); if ( sx != nsx || sy != nsy ) return(1); bqc =(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); logmsg(is_verbose,"Calculating biquadratic coefficients... "); biquad_coeff(img->data,sx,sy,bqc,mask); logmsg(is_verbose,"done.\n"); for ( i=0 ; idata[i][j]=biquad_scatter(bqc,j,i); else outmask[i][j]=mask[i][j],outimg->data[i][j]=0.0; } } tensor_free(bqc); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int trim_image (fitsimage *img,char **mask,fitsimage *outimg,char **outmask, int ofx,int ofy) { int sx,sy,nsx,nsy; int i,j,ii,jj,m; if ( img==NULL || outimg==NULL ) return(1); if ( mask==NULL || outmask==NULL ) return(1); sx=img->sx, sy=img->sy; nsx=outimg->sx; nsy=outimg->sy; if ( sx==0 || sy==0 || nsx==0 || nsy==0 ) return(0); for ( i=0 ; i=sy || jj>=sx ) { m|=MASK_OUTER, outimg->data[i][j]=0.0; } else { m|=mask[ii][jj]; outimg->data[i][j]=img->data[ii][jj]; } outmask[i][j]=m; } } return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { FILE *fw,*fr; int i,is_help,is_flip_x,is_flip_y,is_invert,is_shift; fits *img,*outimg; int ofx,ofy,nsx,nsy,frameno,layer,do_median,do_avg_mode; char *outimgfile,*inimgfile,*transfile,*transparam,*basename, **inmasklist,*inweightfile; int zratio,gratio,sratio,bqscatt,int_method; char **mask,**outmask,*fdpstring; char *smoothparam; char *explode_basename; transformation trf_data,*trf=&trf_data; fitsdataparam fdp; weightlist wl_data,*wl; smooth sp; double shift_dx,shift_dy; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; outimgfile=inimgfile=transfile=inweightfile=transparam=NULL;inmasklist=NULL; is_comment=is_verbose=is_help=0;zratio=sratio=gratio=bqscatt=0; ofx=ofy=is_flip_x=is_flip_y=nsx=nsy=0;int_method=is_invert=0; do_median=do_avg_mode=0; frameno=0; smoothparam=NULL; explode_basename=NULL; is_shift=0; shift_dx=shift_dy=0.0; fdp.bitpix=0;fdp.is_scale=0;fdp.bscale=1.0;fdp.bzero=0.0;fdpstring=NULL; sp.type=SMOOTH_NONE; sp.filter=SMOOTH_PREFILTER_NONE; layer=-1; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-h|--help:%f%q",&is_help, "-i|--input:%s",&inimgfile, "--frame:%d",&frameno, "-o|--output:%s",&outimgfile, "-t|--transformation:%s",&transparam, "-T|--input-transformation:%s",&transfile, "-W|--input-weight:%s",&inweightfile, "--reverse|--inverse:%f",&is_invert, "-m:%SN0f",&int_method, /* interpolate + steplike */ "-l:%SN1f",&int_method, /* integrate + steplike */ "-c:%SN2f",&int_method, /* interpolate + spline */ "-k:%SN3f",&int_method, /* integrate + spline */ "-M|--input-mask:%t",&inmasklist, "-z|--zoom:%d",&zratio, "-g|--magnify:%d",&gratio, "-r|--shrink:%d",&sratio, "-d|--median:%f",&do_median, "--optimistic-masking:%SN1f",&do_avg_mode, "-n|--noise:%f",&bqscatt, "-a|--smooth:%s",&smoothparam, "-f|--offset:%d,%d",&ofx,&ofy, "-s|--size:%d,%d",&nsx,&nsy, "-e|--shift:%f%g,%g",&is_shift,&shift_dx,&shift_dy, "-y|--layer|--first-layer:%d",&layer, "-x|--explode:%s",&explode_basename, "--flip-x:%f",&is_flip_x, "--flip-y:%f",&is_flip_y, "--flip-xy|--flip-yx:%f%f",&is_flip_x,&is_flip_y, "-b|--bitpix:%d",&fdp.bitpix, "-D|--data:%s",&fdpstring, "--comment:%f",&is_comment,"(C):%f",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-:%w",&inimgfile, "-*|+*:%e", "*:%w",&inimgfile, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fitrans",FITSH_FITRANS_VERSION,is_help); return(0); } else if ( 1=0 ) sp.xorder=sp.yorder=order; if ( sigma>=0.0 ) sp.lower =sp.upper =sigma; if ( hsize>=0 ) sp.fxhsize=sp.fyhsize=hsize; } if ( inweightfile != NULL ) { fits *img; if ( (fr=fopenread(inweightfile))==NULL ) { fprint_error("unable to open input weight file '%s'.",inweightfile); return(1); } img=fits_read(fr); if ( img==NULL ) { fprint_error("unable to interpret input weight file as FITS data."); return(1); } wl=&wl_data; if ( weight_parse_fits(img,wl) ) { fprint_error("unable to interpret input weight file properly."); return(1); } fits_free(img); } else wl=NULL; if ( explode_basename != NULL ) { int i,l,nlayer,sx,sy; fitsimage *fi; if ( ! format_check_if_formatted(explode_basename,"dxXio") ) { fprint_error("invalid explode basename template '%s' (perhaps '%%d' is missing)",explode_basename); return(1); } basename=fits_basename(inimgfile,&frameno); fr=fopenread(basename); if ( fr==NULL ) { fprint_error("unable to access/read input file"); return(1); } if ( (img=fits_seek_frame_to_image(fr,0)) == NULL ) { fprint_error("unable to parse input file as a FITS image"); return(1); } if ( layer<0 ) layer=0; fi=&img->i; nlayer=1; for ( l=2 ; ldim ; l++ ) { nlayer *= fi->naxis[l]; } sx=fi->naxis[0]; if ( fi->dim>1 ) sy=fi->naxis[1]; else sy=1; for ( l=0 ; li.bit=fi->bit; img->i.curr.bscale=fi->curr.bscale; img->i.curr.bzero=fi->curr.bzero; img->i.read.bscale=fi->read.bscale; img->i.read.bzero=fi->read.bzero; fits_set_image_params(img); sprintf(buff,"Created by fitrans, version: %s",FITSH_FITRANS_VERSION); fits_set_origin(img,buff,NULL); fits_history_export_command_line(img,"fitrans",FITSH_FITRANS_VERSION,argc,argv); for ( i=0 ; ibit,img->i.data[i]); } fw=fopenwrite(filename); if ( fw==NULL ) { fprint_error("unable to create output file '%s'",filename); return(1); } fits_write(fw,img); fclosewrite(fw); fits_free(img); free(filename); } fcloseread(fr); return(0); } basename=fits_basename(inimgfile,&frameno); if ( (fr=fopenread(basename))==NULL ) { fprint_error("unable to open input file '%s'.",basename); return(1); } img=fits_read_frame_to_image(fr,frameno); fclose(fr); if ( img==NULL ) { fprint_error("unable to interpret input as FITS data."); return(1); } if ( img->i.dim != 2 && layer<0 ) { fprint_error("image dimension differs from 2 and no layer has been specified."); return(1); } else if ( img->i.dim == 3 && layer>=0 && layeri.naxis[2] ) { fitsimage fi; int i,sx,sy; double ***dcube; sx=img->i.naxis[0]; sy=img->i.naxis[1]; fits_image_alloc(&fi,sx,sy); fi.bit=img->i.bit; fi.curr=img->i.curr; fi.read=img->i.read; dcube=(double ***)img->i.vdata; for ( i=0 ; ii); img->i=fi; fits_image_set_params(&img->header,&img->i); } fits_rescale(img); logmsg(is_verbose,"[%d,%d]\n",img->i.sx,img->i.sy); /* Create the mask for the valid pixels: */ mask=fits_mask_read_from_header(&img->header,img->i.sx,img->i.sy,NULL); if ( inmasklist != NULL ) { if ( join_masks_from_files(mask,img->i.sx,img->i.sy,inmasklist) ) { fprint_error("unable to read one of the input mask files"); return(1); } } fits_mask_mark_nans(&img->i,mask,MASK_NAN); if ( nsx<0 ) is_flip_x=!is_flip_x,nsx=-nsx; if ( nsy<0 ) is_flip_y=!is_flip_y,nsy=-nsy; if ( nsx==0 && nsy==0 ) { if ( zratio>1 ) nsx=img->i.sx*zratio, nsy=img->i.sy*zratio; else if ( gratio>1 ) nsx=img->i.sx*gratio, nsy=img->i.sy*gratio; else if ( sratio>1 ) nsx=(img->i.sx+sratio-1)/sratio, nsy=(img->i.sy+sratio-1)/sratio; else nsx=img->i.sx, nsy=img->i.sy; } /* Create new FITS image for the output: */ outimg=fits_duplicate_empty(img); if ( nsx != img->i.sx || nsy != img->i.sy ) { fits_free_image(outimg); fits_alloc_image(outimg,nsx,nsy); fits_reset_image(outimg); fits_set_header_integer(outimg,"NAXIS1",FITS_SH_FIRST,nsx,NULL); fits_set_header_integer(outimg,"NAXIS2",FITS_SH_FIRST,nsy,NULL); } outmask=fits_mask_create_empty(nsx,nsy); /* Read transformation file, if it has been specified in the command line: */ if ( transfile != NULL ) { FILE *ft; ft=fopenread(transfile); if ( ft==NULL ) { fprint_error("unable to open input transformation file '%s'",transfile); return(1); } i=transformation_read_data(ft,trf); if ( i ) { fprint_error("unable to parse the contents of input transformation file '%s'",transfile); return(1); } fcloseread(ft); } else if ( transparam != NULL ) { i=transformation_parse_params(transparam,trf); if ( i ) { fprint_error("unable to parse transformation string '%s'",transparam); return(1); } } else if ( is_shift ) { trf->type=TRANS_POLYNOMIAL; trf->order=1; trf->nval=2; trf->ox=trf->oy=0.0; trf->scale=1.0; trf->vfits=(double **)tensor_alloc_2d(double,3,2); trf->vfits[0][0]=shift_dx; trf->vfits[0][1]=1.0; trf->vfits[0][2]=0.0; trf->vfits[1][0]=shift_dy; trf->vfits[1][1]=0.0; trf->vfits[1][2]=1.0; } else trf=NULL; if ( trf != NULL && trf->nval != 2 ) { fprint_error("input transformation is not an 2D -> 2D transformation"); return(1); } /* Apply the required transformation: */ if ( trf != NULL ) apply_transformation(&img->i,mask,&outimg->i,outmask,ofx,ofy,trf,int_method,is_invert); else if ( zratio>1 ) zoom_image(&img->i,mask,&outimg->i,outmask,ofx,ofy,zratio); else if ( gratio>1 ) zoom_raw_image(&img->i,mask,&outimg->i,outmask,ofx,ofy,gratio); else if ( sratio>1 ) shrink_image(&img->i,mask,&outimg->i,outmask,ofx,ofy,sratio,do_median,do_avg_mode); else if ( bqscatt ) scatter_image(&img->i,mask,&outimg->i,outmask); else if ( sp.type || sp.filter ) combined_smooth_image(&img->i,mask,&outimg->i,outmask,&sp); else trim_image(&img->i,mask,&outimg->i,outmask,ofx,ofy); fits_mask_free(mask); if ( fdp.bitpix ) { outimg->i.bit=fdp.bitpix; } if ( fdp.is_scale ) { outimg->i.read.bscale=fdp.bscale, outimg->i.read.bzero=fdp.bzero; } else if ( outimg->i.bit<0 ) { outimg->i.read.bscale=1.0, outimg->i.read.bzero=0.0; } fits_set_image_params(outimg); fits_backscale(outimg,outimg->i.read.bscale,outimg->i.read.bzero); mark_integerlimited_pixels(&outimg->i,outmask,outimg->i.bit,1,MASK_OVERSATURATED,MASK_OVERSATURATED); /* Write the output image: */ if ( is_flip_y ) { double *pd; char *pc; int i; for ( i=0 ; ii.data[i], outimg->i.data[i]=outimg->i.data[nsy-i-1], outimg->i.data[nsy-i-1]=pd; pc=outmask[i], outmask[i]=outmask[nsy-i-1], outmask[nsy-i-1]=pc; } } if ( is_flip_x ) { double wd; int i,j,wc; for ( i=0 ; ii.data[i][j], outimg->i.data[i][j]=outimg->i.data[i][nsx-1-j]; outimg->i.data[i][nsx-1-j]=wd; wc=outmask[i][j], outmask[i][j]=outmask[i][nsx-1-j], outmask[i][nsx-1-j]=wc; } } } fits_history_export_command_line(outimg,"fitrans",FITSH_FITRANS_VERSION,argc,argv); fits_mask_export_as_header(&outimg->header,1,outmask,nsx,nsy,NULL); if ( outimgfile==NULL ) fw=stdout; else fw=fopenwrite(outimgfile); if ( fw==NULL ) { fprint_error("unable to create output image file '%s'",outimgfile); return(1); } fits_write(fw,outimg); fclosewrite(fw); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/imgtrans.c0000644000175000017500000001402611236250326014035 0ustar apalapal/*****************************************************************************/ /* imgtrans.c [-> fits.c, sort.c] */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Library for applying the discrete spatial operators on FITS images. */ /* The library is NOT standalone, it requires some functions from fits.a */ /* and sort.c */ /* (c) 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in imgtrans.h */ /*****************************************************************************/ #include #include #include #include #include #include #include "statistics.h" #include "index/sort.h" #include "imgtrans.h" /*****************************************************************************/ static int laplace_of_image_ign_flag(fitsimage *img,int flag) { int i,j,sx,sy; double *d0,*d1,*dd; if ( img==NULL ) return(1); if ( img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sy<3 || sx<3 ) { for ( i=0 ; idata[i][j]=0.0; } } return(0); } dd=(double *)malloc(sizeof(double)*sx*2); if ( dd==NULL ) return(-1); d0=dd,d1=d0+sx; for ( j=0 ; jdata[0][j], d1[j]=img->data[1][j]; } for ( i=0 ; idata[i][j]=0.0; } continue; } img->data[i][0]=img->data[i][sx-1]=0.0; if ( ! flag ) { for ( j=1 ; jdata[i][j]=4*d1[j]-(d0[j]+img->data[i+1][j]+d1[j-1]+d1[j+1]); } } else { for ( j=1 ; jdata[i+1][j]<=0.0 ) img->data[i][j]=0.0; else img->data[i][j]=4*d1[j]-(d0[j]+img->data[i+1][j]+d1[j-1]+d1[j+1]); } } if ( idata[i+1][j]; } } } free(dd); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int laplace_of_image(fitsimage *img) { return ( laplace_of_image_ign_flag(img,0) ); } int laplace_of_image_ign(fitsimage *img) { return ( laplace_of_image_ign_flag(img,1) ); } /*****************************************************************************/ static int cyclic_laplace_of_image_ign_flag(fitsimage *img,int flag) { int i,j,sx,sy; double *d0,*d1,*di,*dd; if ( img==NULL ) return(1); if ( img->data==NULL ) return(1); sx=img->sx,sy=img->sy; dd=(double *)malloc(sizeof(double)*sx*3); if ( dd==NULL ) return(-1); di=dd,d0=dd+sx,d1=d0+sx; for ( j=0 ; jdata[0][j], d0[j]=img->data[sy-1][j]; } for ( i=0 ; idata[i+1]; else dnext=di; if ( ! flag ) { img->data[i][0 ]=4*dcurr[0 ]-(dprev[0 ]+dnext[0 ]+dcurr[sx-1]+dcurr[1]); for ( j=1 ; jdata[i][j]=4*dcurr[j]-(dprev[j]+dnext[j]+dcurr[j-1]+dcurr[j+1]); } img->data[i][sx-1]=4*dcurr[sx-1]-(dprev[sx-1]+dnext[sx-1]+dcurr[sx-2]+dcurr[0]); } else { if ( dcurr[0]<=0.0 || dprev[0]<=0.0 || dnext[0]<=0.0 || dcurr[sx-1]<=0.0 || dcurr[1]<=0.0 ) img->data[i][0 ]=0.0; else img->data[i][0 ]=4*dcurr[0 ]-(dprev[0 ]+dnext[0 ]+dcurr[sx-1]+dcurr[1]); for ( j=1 ; jdata[i][j]=0.0; else img->data[i][j]=4*dcurr[j]-(dprev[j]+dnext[j]+dcurr[j-1]+dcurr[j+1]); } if ( dcurr[sx-1]<=0.0 || dprev[sx-1]<=0.0 || dnext[sx-1]<=0.0 || dcurr[sx-2]<=0.0 || dcurr[0]<=0.0 ) img->data[i][sx-1]=0.0; else img->data[i][sx-1]=4*dcurr[sx-1]-(dprev[sx-1]+dnext[sx-1]+dcurr[sx-2]+dcurr[0]); } if ( idata[i+1][j]; } } } free(dd); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int cyclic_laplace_of_image(fitsimage *img) { return ( cyclic_laplace_of_image_ign_flag(img,0) ); } int cyclic_laplace_of_image_ign(fitsimage *img) { return ( cyclic_laplace_of_image_ign_flag(img,1) ); } /*****************************************************************************/ /* static int median_block_filter_compare(int i1,int i2,void *param) { double *rawdata; rawdata=(double *)param; if ( rawdata[i1] < rawdata[i2] ) return(-1); else return(1); } int median_block_filter(fitsimage *img,fitsimage *med,char **mask,int hb) { int sx,sy,i,j,hs; int imin,imax,in,ii, jmin,jmax,jn,jj; int *idx,n; double *rawdata; if ( img==NULL || med==NULL ) return(1); if ( img->data==NULL || med->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx != med->sx || sy != med->sy ) return(1); hs=2*hb+1; rawdata=(double *)malloc(sizeof(double)*hs*sx); if ( rawdata==NULL ) return(-1); idx=(int *)malloc(sizeof(int)*hs*hs); if ( idx==NULL ) return(-1); for ( i=0 ; i=sy ) imax=sy-1; in=imax-imin+1; for ( ii=0 ; iidata[imin+ii],sizeof(double)*sx); } for ( j=0 ; j=sx ) jmax=sx-1; jn=jmax-jmin+1; if ( mask==NULL ) { for ( ii=0,n=0 ; iidata[i][j]=0.0; } else if ( n==1 ) { med->data[i][j]=rawdata[idx[0]]; } else { int p1,p2; index_qsort(idx,n,median_block_filter_compare,(void *)rawdata); p1=(n-1)/2,p2=(n)/2; med->data[i][j]=0.5*(rawdata[idx[p1]]+rawdata[idx[p2]]); } } } free(idx); free(rawdata); return(0); } */ fitsh-0.9.2/src/math/0000755000175000017500000000000012772016355013003 5ustar apalapalfitsh-0.9.2/src/math/trimatch.c0000644000175000017500000005050011237361074014756 0ustar apalapal/***********************b*****************************************************/ /* trimatch.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Triangle match of 2D pointsets. Originally written by Istvan Domsa (see */ /* copyright below), minor modifications (to be 'fi'-compatible) and some */ /* extensions (see expand_triangulation(), new triangle space coordinates */ /* and related functions) were made by A. Pal (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2003; Domsa, I. (domsa@konkoly.hu); 2005-06, Pal, A. (apal@szofi) */ /*****************************************************************************/ /* trimatch.c : triangle match of 2D pointsets (domsa@konkoly.hu (2002)) */ /* code based on Michael Richmond's "match" program (PASP, 107, 1119) */ /* written for the HAT Project */ /* trimatch.c,v 5.5 2003/05/13 16:05:26 domsa Exp */ #include #include #include #include #include #include "fit/lmfit.h" #include "poly.h" #include "polyfit.h" #include "spmatrix.h" #include "cpmatch.h" #include "tpoint.h" #include "delaunay.h" #include "trimatch.h" #define MINVOTE 1 /* pairs get accounted with larger no. of votes */ #define MATCH_PERCENTILE 0.4 /* best 70% used for transformation calc */ #define MATCH_MINSIGMA 1e-06 /* stop iterating if this sigma reached */ #define MATCH_BIGNSIGMA 36.0 /* no pairs above 6sigma distance */ #define MATCH_MAXITER 2 /* how many times to iterate to find trans */ #define MAX(x,y) ((x) > (y) ? (x) : (y)) typedef struct { tpoint *p1; /* ptr to "obj" */ tpoint *p2; /* ptr to "cat" */ union { double votes; /* confidence of matched pairs */ double dist; } confidence; } pair; /* turns triangles into points in "triangle space" */ tpoint *tri2point(int len, triangle *tris) { int ii; tpoint *points,*curr; /* propagate internal error */ if ( len < 1 || tris == NULL ) return(NULL); if ( (points=malloc(len*sizeof(*points))) == NULL ) return(NULL); for ( ii=0, curr=points ; iiid =ii; curr->xcoord=tris[ii].trix; /* "x" is the b/a ratio */ curr->ycoord=tris[ii].triy; /* "y" is the c/a ratio */ } return(points); } static int triangle_sidesquares(triangle *t,double *ret) { ret[0]=(t->vertices[1]->xcoord-t->vertices[2]->xcoord)* (t->vertices[1]->xcoord-t->vertices[2]->xcoord)+ (t->vertices[1]->ycoord-t->vertices[2]->ycoord)* (t->vertices[1]->ycoord-t->vertices[2]->ycoord); ret[1]=(t->vertices[2]->xcoord-t->vertices[0]->xcoord)* (t->vertices[2]->xcoord-t->vertices[0]->xcoord)+ (t->vertices[2]->ycoord-t->vertices[0]->ycoord)* (t->vertices[2]->ycoord-t->vertices[0]->ycoord); ret[2]=(t->vertices[0]->xcoord-t->vertices[1]->xcoord)* (t->vertices[0]->xcoord-t->vertices[1]->xcoord)+ (t->vertices[0]->ycoord-t->vertices[1]->ycoord)* (t->vertices[0]->ycoord-t->vertices[1]->ycoord); return(0); } static int triangle_side_sort(double *s,int *i) { if ( s[0] <= s[1] && s[0] <= s[2] ) { if ( s[1] <= s[2] ) i[0]=0,i[1]=1,i[2]=2; else i[0]=0,i[1]=2,i[2]=1; } else if ( s[1] <= s[0] && s[1] <= s[2] ) { if ( s[0] <= s[2] ) i[0]=1,i[1]=0,i[2]=2; else i[0]=1,i[1]=2,i[2]=0; } else { if ( s[0] <= s[1] ) i[0]=2,i[1]=0,i[2]=1; else i[0]=2,i[1]=1,i[2]=0; } return(0); } /* create a match matrix */ spmatrix *getmatchmatrix(int nobjtri,triangle *objtri,int ncattri,triangle *cattri) { int ii,vote; int hlen; spmatrix *votematrix; tpoint *catpoints, *objpoints; tpointarr *catarr, *objarr; cphit *hits; catpoints=tri2point(ncattri,cattri); objpoints=tri2point(nobjtri,objtri); if ( catpoints==NULL || objpoints==NULL ) { if ( catpoints != NULL ) free(catpoints); if ( objpoints != NULL ) free(objpoints); return(NULL); } catarr=tpoint_buildarr(ncattri,catpoints); objarr=tpoint_buildarr(nobjtri,objpoints); if ( catarr==NULL || objarr==NULL ) { if ( catarr != NULL ) tpoint_destroyarr(catarr); if ( objarr != NULL ) tpoint_destroyarr(objarr); return(0); } if ( (votematrix= spm_create()) == NULL ) { tpoint_destroyarr(catarr); tpoint_destroyarr(objarr); return(NULL); } /* maxdist=1.0; if ( (hits=cpmatch(catarr,objarr,&hlen))==NULL || (hlen=cphit_revise(hlen,&hits,MAX(ncattri,nobjtri),CPMTYPE_ACC,&maxdist)) == 0 ) */ /* try to match as many pairs as possible */ if ( (hits=cpmatch_symmetric(catarr,objarr,&hlen,4.0,0.0)) == NULL ) { tpoint_destroyarr(catarr); tpoint_destroyarr(objarr); spm_destroy(votematrix); return(NULL); } qsort(hits,hlen,sizeof(cphit),cphit_sort_dist); /* fill up vote matrix */ for ( ii=0 ; iiid,cattri[xc].vertices[icat[0]]->id); spm_addval(votematrix,vote,objtri[xo].vertices[iobj[1]]->id,cattri[xc].vertices[icat[1]]->id); spm_addval(votematrix,vote,objtri[xo].vertices[iobj[2]]->id,cattri[xc].vertices[icat[2]]->id); } /* release memory */ tpoint_destroyarr(objarr); tpoint_destroyarr(catarr); return(votematrix); } /* get all non-zero elements from a vote matrix */ pair *get_pairs(spmatrix *votematrix,tpoint *obj,tpoint *cat,int *plen) { int npairs; pair *pairs, *cp; spnode node,witness; /* just to be sure */ if ( votematrix == NULL || obj == NULL || cat == NULL ) return(NULL); if ( (pairs=malloc(spm_numofelems(votematrix)*sizeof(*pairs))) == NULL ) return(NULL); npairs=0;witness=NULL; node=spm_getnextnode(votematrix,NULL,&witness); while ( node != NULL ) { cp=pairs+npairs; cp->p1=obj+spm_getrow(node); cp->p2=cat+spm_getcol(node); cp->confidence.votes=spm_getnodeval(node); npairs++; node=spm_getnextnode(votematrix,node,&witness); } *plen=npairs; return(pairs); } /* sort a list of pairs according to votes (for qsort()) */ int sort_pairs(const void *p1,const void *p2) { int vote1=((pair *)p1)->confidence.votes; int vote2=((pair *)p2)->confidence.votes; return(vote2-vote1); } /* sort a list of pairs according to distances (for qsort()) */ int sort_pairsdist(const void *p1, const void *p2) { double dist1=((pair *)p1)->confidence.dist; double dist2=((pair *)p2)->confidence.dist; return(dist2>dist1 ? -1 : 1); } /* return the "perc"th percentile distance */ double find_percdist(int len, pair *pairs, double perc) { int index=(int)(len*perc+0.5); if ( index >= len ) index=len-1; return(pairs[index].confidence.dist); } /* that's the main stuff: get the linear transform from found pairs */ int calc_trans(int len,pair *pairs,int order,double *xfit,double *yfit,double *sigma) { int ii,k,nvar; point *fpoints; nvar=(order+1)*(order+2)/2; for ( ii=0 ; iixcoord; fpoints[ii].y=pairs[ii].p2->ycoord; fpoints[ii].weight=1.0; } for ( ii=0 ; iixcoord; } k=fit_2d_poly(fpoints,len,order,xfit,0,0,1); if ( ! k ) { for ( ii=0 ; iiycoord; } k=fit_2d_poly(fpoints,len,order,yfit,0,0,1); } free(fpoints); return(k); } /* iterate until the best matching transformation found */ int get_trans(int *len, pair *pairs, int order,double *xfit,double *yfit, double *sumsig, double maxdist) { int length,ii,iter,badnumber; double sigma,bigsigma,nx,ny,dx,dy; /* propagate internal error */ if ( *len < 3 || pairs == NULL ) return(1); if ( maxdist > 0 ) maxdist=maxdist*maxdist; length=*len; /* start iteration */ iter=0; do { /* calculate transformation */ if ( calc_trans(length,pairs,order,xfit,yfit,sumsig) ) return(1); /* calculate euclidian distances of transformed points to their pairs */ for ( ii=0; iixcoord,pairs[ii].p2->ycoord,order,xfit,0,0,1); ny=eval_2d_poly(pairs[ii].p2->xcoord,pairs[ii].p2->ycoord,order,yfit,0,0,1); dx=pairs[ii].p1->xcoord-nx, dy=pairs[ii].p1->ycoord-ny; pairs[ii].confidence.dist=dx*dx+dy*dy; } /* sort pairs along distance */ qsort((void *)pairs,length,sizeof(*pairs),sort_pairsdist); /* no bad point so far */ badnumber=0; /* get rid of pairs which are too separated */ if ( maxdist > 0.0 ) { for ( ii=0 ; ii maxdist ) { badnumber = 1; length = ii; break; } } } /* check if there are any points left */ if ( length==0 ) return(1); /* get sigma for MATCH_PERCENTILE best matches */ sigma=find_percdist(length,pairs,MATCH_PERCENTILE); /* if sigma is too small then stop now */ if ( sigma 0.0 && bigsigma < maxdist) ) { for ( ii=0 ; ii bigsigma ) { badnumber=1; length =ii; break; } } if ( length==0 ) return(1); } } while ( badnumber && ++iter < MATCH_MAXITER ); *len=length; return(calc_trans(length,pairs,order,xfit,yfit,sumsig)); } /* get those pairs with highest votes (ret 0 on error) */ int get_bigvotes(pair *matches, int len) { int ii,jj,min_vote,already; tpoint *cur_obj,*cur_cat; tpoint **already_obj,**already_cat; if ( matches==NULL || len<1 ) return(0); already_obj=malloc(len*sizeof(tpoint *)); already_cat=malloc(len*sizeof(tpoint *)); if ( already_obj==NULL || already_cat==NULL ) { if ( already_obj != NULL ) free(already_obj); if ( already_cat != NULL ) free(already_cat); return(0); } memset(already_obj,0,len*sizeof(tpoint *)); memset(already_cat,0,len*sizeof(tpoint *)); min_vote=MINVOTE; already =0; for ( ii=0 ; iivertices[0]; p1=tt->vertices[1]; p2=tt->vertices[2]; x1=p1->xcoord-p0->xcoord,y1=p1->ycoord-p0->ycoord; x2=p2->xcoord-p0->xcoord,y2=p2->ycoord-p0->ycoord; if ( (double)parity*(x1*y2-y1*x2) < 0.0 ) pt=tt->vertices[2],tt->vertices[2]=tt->vertices[1],tt->vertices[1]=pt; return(0); } int triangle_sort_ccw(triangle *tt) { return ( triangle_sort(tt,+1) ); } int triangle_sort_cw(triangle *tt) { return ( triangle_sort(tt,-1) ); } int triangle_space_coords_mixed(triangle *tt) { tpoint *p0,*p1,*p2,*sorted[3]; double sides[3],ab,ac; p0=tt->vertices[0]; p1=tt->vertices[1]; p2=tt->vertices[2]; sides[0]=tpoint_eucdist(p1,p2),sorted[0]=p0; sides[1]=tpoint_eucdist(p2,p0),sorted[1]=p1; sides[2]=tpoint_eucdist(p0,p1),sorted[2]=p2; vertice_sort(sides,sorted); ab=sides[1]/sides[0]; ac=sides[2]/sides[0]; tt->trix=ab; tt->triy=ac; tt->vertices[0]=sorted[0], tt->vertices[1]=sorted[1], tt->vertices[2]=sorted[2]; triangle_sort_ccw(tt); return(0); } int triangle_space_coords_continous(triangle *tt,int parity) { tpoint *p0,*p1,*p2; double s0,s1,s2,alpha,beta,n2,x,y,r,px,py,ir3; if ( parity>0 ) triangle_sort_ccw(tt); else triangle_sort_cw(tt); p0=tt->vertices[0]; p1=tt->vertices[1]; p2=tt->vertices[2]; s0=tpoint_eucdist(p1,p2); s1=tpoint_eucdist(p2,p0); s2=tpoint_eucdist(p0,p1); if ( s0>=s1 && s0>=s2 ) { alpha=1.0-s1/s0, beta =1.0-s2/s0; } else if ( s1>=s0 && s1>=s2 ) { alpha=1.0-s2/s1, beta =1.0-s0/s1; } else { alpha=1.0-s0/s2, beta =1.0-s1/s2; } n2=sqrt(alpha*alpha+beta*beta); if ( n2 <= 0.0 ) { tt->trix=0.0; tt->triy=0.0; } else { x=alpha*(alpha+beta)/n2; y=beta *(alpha+beta)/n2; r=alpha+beta; ir3=1.0/(r*r*r); px=x*x-y*y; py=2*x*y; tt->trix=ir3*(px*px-py*py); tt->triy=ir3*(2*px*py); } return(0); } int set_triangle_space_coords(triangle *tris,int ntri,int parity) { if ( ! parity ) { while ( ntri>0 ) { triangle_space_coords_mixed(tris); tris++;ntri--; }; } else if ( parity>0 ) { while ( ntri>0 ) { triangle_space_coords_continous(tris,+1); tris++;ntri--; }; } else { while ( ntri>0 ) { triangle_space_coords_continous(tris,-1); tris++;ntri--; }; } return(0); } /*****************************************************************************/ triangle *full_triangulation(tpoint *points,int len,int *ntri) { int numtri; tpoint *p1,*p2,*p3,*e1,*e2,*e3; triangle *triangles,*tt; *ntri=0; if ( len<3 || points==NULL ) return(NULL); /* set boundaries */ e1=points+len-2; e2=points+len-1; e3=points+len; numtri=(len)*(len-1)*(len-2)/6; triangles=malloc(numtri*sizeof(triangle)); if ( triangles==NULL ) return(NULL); for ( p1=points,tt=triangles ; p1vertices[0]=p1, tt->vertices[1]=p2, tt->vertices[2]=p3; tt->trix=tt->triy=0.0; } } } if ( ntri != NULL ) *ntri=numtri; return(triangles); } int copy_triangulation(triangle *tris,int ntri,triangle **rtris,int *rntri) { if ( rtris==NULL || rntri==NULL ) return(1); *rtris=(triangle *)malloc(sizeof(triangle)*ntri); memcpy(*rtris,tris,sizeof(triangle)*ntri); *rntri=ntri; return(0); } int trimatch_int(tpoint *cat,int catlen,tpoint *obj,int objlen, triangle *cattri,int ncattri,triangle *objtri,int nobjtri, int order,double *xfit,double *yfit,double *rsigma,double maxdist, int parity, pair **rmatches,int *rnbigs) { spmatrix *matchmatrix; pair *matches; int nbigs,plen,ret; matchmatrix=NULL; matches=NULL; if ( ! parity ) { set_triangle_space_coords(cattri,ncattri,0); set_triangle_space_coords(objtri,nobjtri,0); } else { set_triangle_space_coords(cattri,ncattri,1); set_triangle_space_coords(objtri,nobjtri,parity); } /* get match matrix */ matchmatrix=getmatchmatrix(nobjtri,objtri,ncattri,cattri); if ( matchmatrix == NULL ) return(1); /* get matches */ matches=get_pairs(matchmatrix,obj,cat,&plen); spm_destroy(matchmatrix); if ( matches == NULL ) return(1); /* sort pairs according to votes */ qsort((void *)matches,plen,sizeof(*matches),sort_pairs); /* get pairs with biggest number of votes */ nbigs=get_bigvotes(matches,plen); /* calculate transformation between catalog and image */ ret=get_trans(&nbigs,matches,order,xfit,yfit,rsigma,maxdist); if ( ret ) { free(matches); if ( rmatches != NULL ) *rmatches=NULL; if ( rnbigs != NULL ) *rnbigs=0; return(1); } else { if ( rmatches != NULL ) *rmatches=matches; if ( rnbigs != NULL ) *rnbigs=nbigs; return(0); } } /* trimatch_unitarity(): deprecated, use calc_2d_unitarity() instead. */ /* double trimatch_unitarity(double *xfit,double *yfit) { double ma,mb,mc,md; double n1,n2,nn,dd; double unitarity; ma=xfit[1],mb=xfit[2]; mc=yfit[1],md=yfit[2]; n1=(ma-md)*(ma-md)+(mb+mc)*(mb+mc); n2=(ma+md)*(ma+md)+(mb-mc)*(mb-mc); nn=(n1 this is f*** unclear */ stmp.unitarity=0.0; /* - no automatic unitarity usage */ stmp.parity=0; /* - mixed left/right-handed triangles */ tmp=&stmp; } unitarity=-1.0; if ( tmp->unitarity <= 0.0 ) { if ( tmp->level < 0 ) /* full triangulation */ { objtris=full_triangulation(obj,objlen,&nobjtri); if ( objtris==NULL ) return(1); cattris=full_triangulation(cat,catlen,&ncattri); if ( cattris==NULL ) { free(objtris);return(1); } /* no delaunay triangulation */ catdeltris=NULL,ncatdeltri=0; objdeltris=NULL,nobjdeltri=0; /* no extra triangulation info */ cati.neigs=NULL,cati.neigpoints=NULL; obji.neigs=NULL,obji.neigpoints=NULL; level_init=-1; level_used=-1; } else { int ro,rc; ro=delaunay_triangulation(obj,objlen,&objdeltris,&nobjdeltri,&obji); if ( ro ) return(1); rc=delaunay_triangulation(cat,catlen,&catdeltris,&ncatdeltri,&cati); if ( rc ) { free(objdeltris); free(obji.neigs);free(obji.neigpoints); return(1); } if ( tmp->level>0 ) { expand_triangulation(&cati,&cattris,&ncattri,cat,catlen,tmp->level); expand_triangulation(&obji,&objtris,&nobjtri,obj,objlen,tmp->level); } else { copy_triangulation(catdeltris,ncatdeltri,&cattris,&ncattri); copy_triangulation(objdeltris,nobjdeltri,&objtris,&nobjtri); } level_init=tmp->level; level_used=tmp->level; } ret=trimatch_int(cat,catlen,obj,objlen,cattris,ncattri,objtris,nobjtri, order,xfit,yfit,&sigma,tmp->maxdist,tmp->parity,&matches,&nbigs); free(objtris); free(cattris); } else { int ro,rc; ro=delaunay_triangulation(obj,objlen,&objdeltris,&nobjdeltri,&obji); if ( ro ) return(1); rc=delaunay_triangulation(cat,catlen,&catdeltris,&ncatdeltri,&cati); if ( rc ) { free(objdeltris); free(obji.neigs);free(obji.neigpoints); return(1); } matches=NULL; ret=trimatch_int(cat,catlen,obj,objlen,catdeltris,ncatdeltri,objdeltris,nobjdeltri, order,xfit,yfit,&sigma,tmp->maxdist,tmp->parity,&matches,&nbigs); /*fprintf(stderr,"ret_0=%d\n",ret);*/ for ( level=1 ; level<=4 ; level++ ) { unitarity=calc_2d_unitarity(xfit,yfit,order); /*fprintf(stderr,"unitarity: %g\n",unitarity);*/ if ( unitarity < 0.0 ) ret=1; else if ( unitarity > tmp->unitarity ) ret=1; if ( ! ret ) break; if ( matches != NULL ) { free(matches); matches=NULL; } expand_triangulation(&cati,&cattris,&ncattri,cat,catlen,level); expand_triangulation(&obji,&objtris,&nobjtri,obj,objlen,level); ret=trimatch_int(cat,catlen,obj,objlen,cattris,ncattri,objtris,nobjtri, order,xfit,yfit,&sigma,tmp->maxdist,tmp->parity,&matches,&nbigs); free(objtris); free(cattris); } level_init=0; level_used=level-1; } if ( ! ret && matches != NULL ) { if ( (hits=malloc(sizeof(cphit)*nbigs)) != NULL ) { int ii; for ( ii=0 ; iiid; hits[ii].idx[1]=matches[ii].p1->id; } } nhit=nbigs; } else hits=NULL,nhit=0; if ( matches != NULL ) free(matches); if ( catdeltris != NULL ) free(catdeltris); if ( cati.neigs != NULL ) free(cati.neigs); if ( cati.neigpoints != NULL ) free(cati.neigpoints); if ( objdeltris != NULL ) free(objdeltris); if ( obji.neigs != NULL ) free(obji.neigs); if ( obji.neigpoints != NULL ) free(obji.neigpoints); if ( rhits != NULL ) *rhits=hits; if ( rnhit != NULL ) *rnhit=nhit; if ( tml != NULL ) { tml->residual =sigma; tml->level_init=level_init; tml->level_used=level_used; if ( unitarity < 0.0 ) { unitarity=calc_2d_unitarity(xfit,yfit,order); } tml->unitarity=unitarity; } return(ret); } /*****************************************************************************/ fitsh-0.9.2/src/math/cpmatch.c0000644000175000017500000003145411116251723014564 0ustar apalapal/*****************************************************************************/ /* cpmatch.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to point matching: */ /* - matching between two 2d point sets; */ /* - searching for nearest point in a given point list; */ /* - searching for neighbouring points in a given point list. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Written by Istvan Domsa (see original copyright below) and */ /* A. Pal (apal@szofi.elte.hu). (c) 2003, 2005-2006 */ /*****************************************************************************/ /* cpmatch.c : match two 2D point array (domsa@konkoly.hu (2003)) */ /* cpmatch.c,v 5.5 2003/05/13 16:09:43 domsa Exp */ #include #include #include #include #include "tpoint.h" #include "cpmatch.h" #define FLT_EPSILON 1e-10 #define SWAP(a,b,type) do {type t;t=a;a=b;b=t;} while (0) /*****************************************************************************/ /* function for qsort() interface: sort hit array along distance */ int cphit_sort_dist(const void *p1, const void *p2) { double d1=((cphit *)p1)->distance; double d2=((cphit *)p2)->distance; return(d1>d2?1:-1); } /*****************************************************************************/ /* return the index of the point in the base array, whose x coord is just below or equals the xcoord of the probe point. base array should be sorted along its x coordinates. return a negative number on error */ int cpmatch_find_xidx(tpoint *probe,tpointarr *base) { int min,max,mid; double xcoord,dist; tpoint *arr; mid = -1; /* set return value to something invalid */ min =0; max =base->length; arr =base->points; xcoord=probe->xcoord; while ( max > min ) { mid = (max + min)/2; dist = xcoord - arr[mid].xcoord; if ( fabs(dist) < FLT_EPSILON ) break; else if ( dist > 0.0 ) min = mid + 1; else max = mid; } return(mid); } /* find the closest point in a direction. return negative number on error */ int cpmatch_find_nearest(tpoint *probe,tpointarr *base,int neighbour, double *rdistance,int is_exclude_self) { int posl,posr,best; int length; double xc,yc,xx,yy; double xdist,ydist; double xcoord,ycoord; double maxdist,cdist; double mindist,dist; tpoint *basearr,*nbpoint; int outl,outr; /* check if neighbour point is inside the array */ length = base->length; if ( neighbour < 0 || neighbour >= length ) return(-1); /* x/y coordantes of the probe point */ xcoord = probe->xcoord; ycoord = probe->ycoord; /* array of the base points */ basearr = base->points; /* the point to start the search with: */ /* if the index with 'neighbour' is not excluded... */ if ( ! is_exclude_self ) { /* x/y distances from the probe and its neighbouring point */ nbpoint = basearr + neighbour; xdist = fabs(nbpoint->xcoord-xcoord); ydist = fabs(nbpoint->ycoord-ycoord); /* calculate the initial squared minimal distance, and set best poss */ best =neighbour; mindist=xdist*xdist+ydist*ydist; maxdist=xdist+ydist; } /* ... or if the index with 'neighbour' is excluded: */ else { xdist=ydist=maxdist=mindist=0.0; if ( neighbour>0 ) { nbpoint=basearr+neighbour-1; xdist=fabs(nbpoint->xcoord-xcoord); ydist=fabs(nbpoint->ycoord-ycoord); best =neighbour-1; mindist=xdist*xdist+ydist*ydist; maxdist=xdist+ydist; } else { best=-1; } if ( neighbourxcoord-xcoord); ydist=fabs(nbpoint->ycoord-ycoord); if ( best<0 || xdist*xdist+ydist*ydist= 0 ) { /* the nearest neighbour candidate on the left */ nbpoint = basearr + posl; /* its coordinates */ xc = nbpoint->xcoord; yc = nbpoint->ycoord; /* break out from loop if it's too far away */ xx = xcoord - xc; if ( xx < maxdist ) { yy = yc - ycoord; yy = fabs(yy); /* calculate distance only, if ycoord is less than before */ if ( yy <= ydist ) { ydist = yy; dist = xx*xx + yy*yy; if ( dist <= mindist ) { /* a better match found */ best = posl; mindist = dist; /* xx should be positive */ xx=fabs(xx); /* reset limit */ cdist=xx+yy; if ( cdist < maxdist ) maxdist = cdist; } } } else outl=0; } else outl=0; } if ( outr ) { if ( posr < length ) { /* the nearest neighbour candidate on the right */ nbpoint = basearr + posr; /* and its coordinates */ xc = nbpoint->xcoord; yc = nbpoint->ycoord; /* break out from loop if it's too far away */ xx = xc - xcoord; if ( xx < maxdist ) { yy = yc - ycoord; yy = fabs(yy); /* calculate distance only, if ycoord is less than before */ if ( yy <= ydist ) { ydist = yy; dist = xx*xx + yy*yy; if ( dist <= mindist ) { /* a better match found */ best =posr; mindist=dist; /* xx should be positive */ xx=fabs(xx); /* reset limit */ cdist = xx + yy; if ( cdist < maxdist ) maxdist = cdist; } } } else outr=0; } else outr=0; } } /* set minimal distance and return the closest point index */ if ( rdistance != NULL ) *rdistance = mindist; return(best); } int cpmatch_find_neighbour(tpointarr *base,int indx) { int neighbour; tpoint *probe; if ( base->length<=1 ) return(-1); if ( indx<0 || indx>=base->length ) return(-1); probe=&base->points[indx]; neighbour=cpmatch_find_nearest(probe,base,indx,NULL,1); return(neighbour); } /* find closest point matches between two point arrays (see point.h) * returns matches in the hit structure (see cpmatch.h) */ cphit *cpmatch(tpointarr *base,tpointarr *probe, int *hlen) { int ii,pos; int baselen,probelen; int bidx,pidx; tpoint *basearr,*probearr,*pp; cphit *hits; /* set return values */ pos = 0; *hlen = 0; /* check arguments */ if ( base ==NULL || base->points ==NULL || base->length <1 || probe==NULL || probe->points==NULL || probe->length<1 ) return(NULL); bidx=0,pidx=1; /* shortcuts to variables in the structures */ baselen = base->length; basearr = base->points; probelen = probe->length; probearr = probe->points; /* allocate return structure */ if ( (hits = malloc(probelen*sizeof(*hits))) == NULL ) return(NULL); /* sort the base point array along the x-axis */ qsort((void *)basearr,baselen,sizeof(*basearr),tpoint_sortx); /* step through the probe points, and find its closest neighbour among the base points */ for ( pp = probearr, ii = probelen ; ii-- ; pp++ ) { double mindist=0.0; /* cp distance squared */ int neighbour,best; /* neighbour is the index to start the search with */ neighbour = cpmatch_find_xidx(pp, base); /* closest neighbour index in the base array */ best = cpmatch_find_nearest(pp, base, neighbour, &mindist,0); /* save hit to the return structure */ hits[pos].idx[pidx] = pp - probearr; hits[pos].idx[bidx] = basearr[best].id; hits[pos].distance = mindist; /* increment counter of the return length */ pos++; } /* resize array if needed */ if ( pos < probelen ) hits = realloc((void *) hits, pos*sizeof(*hits)); /* reset hits array to NULL, if it was freed by realloc() */ if ( !pos ) hits=NULL; /* return length too */ *hlen = pos; return(hits); } /* find closest point matches between two point arrays */ cphit *cpmatch_symmetric(tpointarr *cat1,tpointarr *cat2, int *hlen,double rev_sig,double rev_maxdist) { int i,j,k,pos; int cat1len,cat2len,maxlen; tpoint *cat1arr,*cat2arr; cphit *hits,*whits; int neighbour,best; double mindist=0.0,meddist,limdist; /* set return values */ *hlen = 0; /* check arguments */ if ( cat1==NULL || cat1->points==NULL || cat1->length<1 || cat2==NULL || cat2->points==NULL || cat2->length<1 ) return(NULL); /* shortcuts to variables in the structures */ cat1len = cat1->length,cat1arr = cat1->points; cat2len = cat2->length,cat2arr = cat2->points; /* fix ids */ /* for ( i=0 ; icat2len?cat1len:cat2len); hits =(cphit *)malloc(maxlen*sizeof(cphit)); whits=(cphit *)malloc(maxlen*sizeof(cphit)); for ( i=0 ; i0.0 ) { qsort(hits,pos,sizeof(cphit),cphit_sort_dist); meddist=0.5*(hits[(pos-1)/2].distance+hits[pos/2].distance); limdist=meddist*rev_sig*rev_sig; while ( pos>0 && hits[pos-1].distance>limdist ) pos--; } if ( rev_maxdist>0.0 ) { qsort(hits,pos,sizeof(cphit),cphit_sort_dist); limdist=rev_maxdist*rev_maxdist; while ( pos>0 && hits[pos-1].distance>limdist ) pos--; } hits=(cphit *)realloc(hits,pos*sizeof(cphit)); qsort((void *)cat1arr,cat1len,sizeof(tpoint),tpoint_sortid); qsort((void *)cat2arr,cat2len,sizeof(tpoint),tpoint_sortid); /* reset hits array to NULL, if it was freed by realloc() */ if ( ! pos ) hits=NULL; /* return length too */ *hlen = pos; return(hits); } /* sort out "good" matches from a hits list. return the new length of the size of the input hit array */ int cphit_revise(int hlen,cphit **hits,int maxhlen,cpmtype mtype,double *maxdist) { int ii, newlen; int *idx0,*idx1; int probe; /* shortcut to the input array */ cphit *hh=*hits; /* check parameters: propagate error */ if ( hlen < 1 || hh == NULL ) return(hlen); /* init return value */ newlen = 0; /* allocate memory for temp index arrays */ if ( (idx0 = malloc(maxhlen*sizeof(int))) == NULL || (idx1 = malloc(maxhlen*sizeof(int))) == NULL ) { free(idx0); return(hlen); } memset(idx0,0,maxhlen*sizeof(int)); memset(idx1,0,maxhlen*sizeof(int)); /* sort input array according to distance */ qsort((void *) hh, hlen, sizeof(*hh), cphit_sort_dist); if ( mtype == CPMTYPE_GUESS ) { for ( ; newlen < hlen ; newlen++ ) { /* check the first index */ probe = hh[newlen].idx[0]; if ( idx0[probe] ) break; else idx0[probe]=1; /* check the second index */ probe = hh[newlen].idx[1]; if ( idx1[probe] ) break; else idx1[probe]=1; } } else if ( mtype == CPMTYPE_ACC ) { int keepon=1; double misses=0.0; /* accumulate error: do not break out at the first unambigous match */ for ( ii = 0 ; keepon && ii < hlen ; ii++ ) { /* check the first index */ probe = hh[ii].idx[0]; if ( idx0[probe] ) { misses += 1.0; if ( misses/newlen >= *maxdist ) keepon=0; continue; } else idx0[probe]=1; /* check the second index */ probe = hh[ii].idx[1]; if ( idx1[probe] ) { misses += 1.0; if ( misses/newlen >= *maxdist ) keepon=0; continue; } else idx1[probe]=1; /* increase new length counter */ newlen++; } } else if ( mtype == CPMTYPE_DIST && maxdist != NULL ) { /* we have a user set maximal distance level */ double md; md=(*maxdist)*(*maxdist); for ( ii = 0 ; ii < hlen && hh[ii].distance < md ; ii++ ) { /* check the first index */ probe = hh[ii].idx[0]; if ( idx0[probe] ) continue; else idx0[probe]=1; /* check the second index */ probe = hh[ii].idx[1]; if(idx1[probe] ) continue; else idx1[probe]=1; /* check the second index */ newlen++; } } /* write maximal distance of unambigous pairs if asked for */ if ( maxdist != NULL ) *maxdist=hh[newlen-1].distance; /* release temp arrays */ free(idx0); free(idx1); /* reallocate the hits array */ if ( newlen != hlen ) *hits=realloc((void *)hh,newlen*sizeof(*hh)); /* set original position if there was an error when reallocating */ if ( *hits==NULL ) *hits=hh; return(newlen); } /*****************************************************************************/ fitsh-0.9.2/src/math/delaunay.c0000644000175000017500000004033011116253736014746 0ustar apalapal/*****************************************************************************/ /* delaunay.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to Delaunay-triangulation. Written by Istvan Domsa (see */ /* original copyright below), minor modifications (to be 'fi'-compatible) */ /* and extensions (see `make_neighbour_list()` and realted functions) */ /* were made by A. Pal (apal@szofi.elte.hu). */ /*****************************************************************************/ /* triangulation.c : triangulate data points (domsa@konkoly.hu (2002)) */ /* written for the HAT Project */ /* triangulation.c,v 5.5 2003/05/13 16:09:44 domsa Exp */ #include #include #include #include #include "tpoint.h" #include "delaunay.h" /* some shortcuts */ #define SWAP(a,b,type) do { type tmp;tmp=a;a=b;b=tmp; } while(0) #define VECTOR(p1,p2,u,v) ( (u)=(p2)->x-(p1)->x,(v)=(p2)->y-(p1)->y ) #define CROSS_PROD_3P(p1,p2,p3) (((p2)->x-(p1)->x)*((p3)->y-(p1)->y)-((p2)->y-(p1)->y)*((p3)->x-(p1)->x)) #define CROSS_PROD_2V(u1,v1,u2,v2) ( (u1)*(v2)-(v1)*(u2) ) #define DOT_PROD_2V(u1,v1,u2,v2) ( (u1)*(u2)+(v1)*(v2) ) #define OTHER_POINT(e,p) ( (e)->orig==p ? (e)->dest : (e)->orig ) #define PREV(e,p) ( (e)->orig==p ? (e)->oprev : (e)->dprev ) #define NEXT(e,p) ( (e)->orig==p ? (e)->onext : (e)->dnext ) #define IDENT_REFS(e1,e2) ( (e1)==(e2) ) typedef enum { right, left } side; typedef struct edge edge; typedef struct dpoint dpoint; struct edge { dpoint *orig; dpoint *dest; edge *onext,*oprev; edge *dnext,*dprev; edge *next,*prev; }; struct dpoint { int ident; double x,y; edge *entry_pt; }; #define LISTSIZE 128 typedef struct { edge *first; edge *last; } tridata; /* cross product of two points */ static void crossdot_prod(dpoint *p1,dpoint *p2,dpoint *p3,double *cross,double *dot) { double dx1,dx2,dy1,dy2; VECTOR(p1,p2,dx1,dy1); VECTOR(p1,p3,dx2,dy2); *cross=CROSS_PROD_2V(dx1,dy1,dx2,dy2); *dot = DOT_PROD_2V(dx1,dy1,dx2,dy2); return; } /* sort the vertices of the triangles */ void vertice_sort(double *sides,tpoint **vertices) { if ( sides[0]first=NULL; td->last=NULL; return(0); } static int tri_fini(tridata *td) { edge *e,*n; for ( e=td->first ; e != NULL ; ) { n=e->next; free(e); e=n; }; return(0); } static edge * tri_edge_alloc(tridata *td) { edge *e; e=(edge *)malloc(sizeof(edge)); if ( td->first==NULL ) { td->first=e; } e->prev=td->last; e->next=NULL; if ( e->prev != NULL ) e->prev->next=e; td->last=e; return(e); } static int tri_edge_free(tridata *td,edge *e) { if ( e->prev != NULL ) e->prev->next=e->next; if ( e->next != NULL ) e->next->prev=e->prev; if ( td->first==e ) td->first=e->next; if ( td->last==e ) td->last=e->prev; free(e); return(0); } /* create an edge */ static edge *makeedge(tridata *td,dpoint *p1,dpoint *p2) { edge *ne; if ( p1==NULL || p2==NULL ) return(NULL); ne=tri_edge_alloc(td); /* ne=(edge *)malloc(sizeof(edge)); */ ne->orig=p1; ne->dest=p2; ne->onext=ne; ne->oprev=ne; ne->dnext=ne; ne->dprev=ne; if ( p1->entry_pt==NULL ) p1->entry_pt=ne; if ( p2->entry_pt==NULL ) p2->entry_pt=ne; return(ne); } /* delete an edge */ static void deledge(tridata *td,edge *ed) { dpoint *p1,*p2; if ( ed==NULL ) return; p1=ed->orig; p2=ed->dest; /* adjust entry points */ if ( p1->entry_pt==ed ) p1->entry_pt=ed->onext; if ( p2->entry_pt==ed ) p2->entry_pt=ed->dnext; /* four edge links to change */ if ( (ed->onext)->orig==p1 ) (ed->onext)->oprev=ed->oprev; else (ed->onext)->dprev=ed->oprev; if ( (ed->oprev)->orig==p1 ) (ed->oprev)->onext=ed->onext; else (ed->oprev)->dnext=ed->onext; if ( (ed->dnext)->orig==p2 ) (ed->dnext)->oprev=ed->dprev; else (ed->dnext)->dprev=ed->dprev; if ( (ed->dprev)->orig==p2 ) (ed->dprev)->onext=ed->dnext; else (ed->dprev)->dnext=ed->dnext; tri_edge_free(td,ed); /* free(ed); */ return; } /* add an edge to a ring of edges */ static void spliceedge(tridata *td,edge *e1,edge *e2,dpoint *pp) { edge *next; /* e2 must be the unnattached edge and e1 the previous ccw edge to e2 */ if ( e1->orig==pp ) next=e1->onext,e1->onext=e2; else next=e1->dnext,e1->dnext=e2; if ( next->orig==pp ) next->oprev=e2; else next->dprev=e2; if ( e2->orig==pp ) e2->onext=next,e2->oprev=e1; else e2->dnext=next,e2->dprev=e1; return; } /* creates a new edge and adds it to two rings of edges */ /* p1 and p2 are the two vertices which are being joined */ /* e1 and e2 are the two edges associated with u and v respectively */ static edge *joinedge(tridata *td,edge *e1,dpoint *p1,edge *e2,dpoint *p2,side sd) { edge *enew; if ( (enew=makeedge(td,p1,p2))==NULL ) return(NULL); if ( sd==left ) { if ( e1->orig==p1 ) spliceedge(td,e1->oprev,enew,p1); else spliceedge(td,e1->dprev,enew,p1); spliceedge(td,e2,enew,p2); } else { spliceedge(td,e1,enew,p1); if ( e2->orig==p2 ) spliceedge(td,e2->oprev,enew,p2); else spliceedge(td,e2->dprev,enew,p2); } return(enew); } /* lower tangent of two triangulation */ static void lower_tangent(tridata *td,edge *r_cw_l,dpoint *p1,edge *l_ccw_r,dpoint *p2, edge **l_lower,dpoint **org_l_lower, edge **r_lower,dpoint **org_r_lower) { edge *eleft,*eright; dpoint *o_l,*o_r,*d_l,*d_r; eleft =r_cw_l; eright=l_ccw_r; o_l =p1; d_l =OTHER_POINT(eleft,p1); o_r =p2; d_r =OTHER_POINT(eright,p2); for ( ; ; ) { if ( CROSS_PROD_3P(o_l,d_l,o_r)>0.0 ) { eleft=PREV(eleft,d_l); o_l =d_l; d_l =OTHER_POINT(eleft,o_l); } else if ( CROSS_PROD_3P(o_r,d_r,o_l)<0.0 ) { eright=NEXT(eright,d_r); o_r =d_r; d_r =OTHER_POINT(eright,o_r); } else break; } *l_lower =eleft; *r_lower =eright; *org_l_lower=o_l; *org_r_lower=o_r; return; } /* merge two adjacent Delaunay triangulations into a single one */ static void mergehulls(tridata *td,edge *r_cw_l,dpoint *p1,edge *l_ccw_r,dpoint *p2,edge **l_tangent) { double c_p_l_cand,c_p_r_cand,d_p_l_cand,d_p_r_cand; double cot_l_cand=0.0,cot_r_cand=0.0; int above_l_cand,above_r_cand; edge *l_lower,*r_lower,*base,*l_cand,*r_cand; dpoint *org_r_lower,*org_l_lower,*org_base,*dest_base; dpoint *dest_l_cand,*dest_r_cand; /* create first cross edge by joining lower common tangent */ lower_tangent(td,r_cw_l,p1,l_ccw_r,p2,&l_lower,&org_l_lower,&r_lower,&org_r_lower); base =joinedge(td,l_lower,org_l_lower,r_lower,org_r_lower,right); org_base =org_l_lower; dest_base=org_r_lower; /* we have to return lower tangent */ *l_tangent=base; /* main merge loop */ for ( ; ; ) { l_cand=NEXT(base,org_base); r_cand=PREV(base,dest_base); dest_l_cand=OTHER_POINT(l_cand,org_base); dest_r_cand=OTHER_POINT(r_cand,dest_base); crossdot_prod(dest_l_cand,org_base,dest_base,&c_p_l_cand,&d_p_l_cand); crossdot_prod(dest_r_cand,org_base,dest_base,&c_p_r_cand,&d_p_r_cand); above_l_cand=c_p_l_cand > 0.0; above_r_cand=c_p_r_cand > 0.0; if ( !above_l_cand && !above_r_cand ) break; /* advance l_cand counter-clockwise, until the in_circle test fails */ if ( above_l_cand ) { double c_p_next,d_p_next,cot_next; edge *next; dpoint *dest_next; cot_l_cand=d_p_l_cand/c_p_l_cand; for ( ; ; ) { next =NEXT(l_cand,org_base); dest_next=OTHER_POINT(next,org_base); crossdot_prod(dest_next,org_base,dest_base,&c_p_next,&d_p_next); if ( c_p_next <= 0.0 ) break; cot_next=d_p_next/c_p_next; if ( cot_next > cot_l_cand ) break; deledge(td,l_cand); l_cand =next; cot_l_cand=cot_next; } } /* advance r_cand clockwise, until the in_circle test fails */ if ( above_r_cand ) { double c_p_prev,d_p_prev,cot_prev; edge *prev; dpoint *dest_prev; cot_r_cand=d_p_r_cand/c_p_r_cand; for ( ; ; ) { prev =PREV(r_cand,dest_base); dest_prev=OTHER_POINT(prev,dest_base); crossdot_prod(dest_prev,org_base,dest_base,&c_p_prev,&d_p_prev); if ( c_p_prev <= 0.0 ) break; cot_prev=d_p_prev/c_p_prev; if ( cot_prev > cot_r_cand ) break; deledge(td,r_cand); r_cand =prev; cot_r_cand=cot_prev; } } /* add a cross edge from base to either l_cand or r_cand */ dest_l_cand=OTHER_POINT(l_cand,org_base); dest_r_cand=OTHER_POINT(r_cand,dest_base); if ( !above_l_cand || (above_l_cand && above_r_cand && cot_r_cand0.0 ) /* make a triangle */ { ec=joinedge(td,ea,pa,eb,pc,right); *l_ccw=ea; *r_cw =eb; } else if ( cp<0.0 ) /* make a triangle */ { ec=joinedge(td,ea,pa,eb,pc,left); *l_ccw=ec; *r_cw =ec; } else /* points are collinear */ { *l_ccw=ea; *r_cw =eb; } } else if ( cardinal > 3 ) { edge *l_ccw_l,*r_cw_l,*l_ccw_r,*r_cw_r,*l_tangent; split=(ileft+iright)/2; divide(td,points,ileft,split,&l_ccw_l,&r_cw_l); divide(td,points,split+1,iright,&l_ccw_r,&r_cw_r); mergehulls(td,r_cw_l,points+split,l_ccw_r,points+split+1,&l_tangent); if ( l_tangent->orig==points+ ileft ) l_ccw_l=l_tangent; if ( l_tangent->dest==points+iright ) r_cw_r =l_tangent; *l_ccw=l_ccw_l; *r_cw =r_cw_r; } return; } /* sort points along the x-axis (for qsort()) */ static int sort_x(const void *p1,const void *p2) { double x1=((dpoint *) p1)->x; double x2=((dpoint *) p2)->x; if ( x1==x2 ) return ( ((dpoint *)p2)->y<((dpoint *)p1)->y ? -1 : 1 ); else return ( x2entry_pt; ep=e_start; if ( e_start==NULL ) /* internal error */ { free(triangles); return(NULL); } do { p2=OTHER_POINT(ep,p1); if ( p1p3 ) SWAP(p2,p3,dpoint *); pn1=points+p1->ident; pn2=points+p2->ident; pn3=points+p3->ident; triangles=realloc(triangles,(numtri+1)*sizeof(*triangles)); triangles[numtri].vertices[0]=pn1; triangles[numtri].vertices[1]=pn2; triangles[numtri].vertices[2]=pn3; triangles[numtri].trix=0.0; triangles[numtri].triy=0.0; numtri++; } } } ep=NEXT(ep,p1); /* next edge around p1 */ } while ( ! IDENT_REFS(ep,e_start) ); } if ( ntri != NULL ) *ntri=numtri; return(triangles); } static int add_neig_point(tpoint ***rneigpoints,int *apnt,int *alen,tpoint *p) { if ( *apnt >= *alen ) { (*rneigpoints)=(tpoint **)realloc((*rneigpoints),sizeof(tpoint *)*((*alen)+LISTSIZE)); (*alen)+=LISTSIZE; } (*rneigpoints)[(*apnt)]=p; (*apnt)++; return(0); } static int make_neighbour_list(dpoint *dpoints,tpoint *tpoints,int n,int *neigindx,triinfo *ti) { int alen,apnt,i; dpoint *d,*nd,*fd; tpoint *t; edge *e; apnt=alen=0; ti->neigpoints=NULL; for ( i=0,d=dpoints ; ientry_pt; nd=fd=OTHER_POINT(e,d); neigindx[d->ident]=apnt; do { t=tpoints+nd->ident; add_neig_point(&ti->neigpoints,&apnt,&alen,t); e=NEXT(e,d); nd=OTHER_POINT(e,d); } while ( nd != fd ); add_neig_point(&ti->neigpoints,&apnt,&alen,NULL); }; return(0); } int delaunay_triangulation(tpoint *points,int len,triangle **rtris,int *rntri,triinfo *ti) { dpoint *dpoints; triangle *tris; int ntri; edge *l_cw,*r_ccw; tridata td; if ( len < 3 || points==NULL ) return(1); if ( (dpoints=point2dpoint(len,points))==NULL ) return(1); qsort((void *)dpoints,len,sizeof(dpoint),sort_x); tri_init(&td); divide(&td,dpoints,0,len-1,&l_cw,&r_ccw); ntri=0; tris=dp2tri(len,points,dpoints,&ntri); if ( ti != NULL ) { int i,*neigindx; neigindx=(int *)malloc(sizeof(int)*len); make_neighbour_list(dpoints,points,len,neigindx,ti); ti->neigs=(tpoint ***)malloc(sizeof(tpoint **)*len); for ( i=0 ; ineigs[i]=&ti->neigpoints[neigindx[i]]; } free(neigindx); } tri_fini(&td); free(dpoints); if ( rtris != NULL ) *rtris=tris; if ( rntri != NULL ) *rntri=ntri; return(0); } /*****************************************************************************/ int free_triangulation_info(triinfo *ti) { if ( ti==NULL ) return(-1); if ( ti->neigpoints != NULL ) { free(ti->neigpoints); ti->neigpoints=NULL; } if ( ti->neigs != NULL ) { free(ti->neigs); ti->neigs=NULL; } return(0); } /*****************************************************************************/ static int compare_triangle_vertices(const void *vp1,const void *vp2) { triangle *t1=(triangle *)vp1; triangle *t2=(triangle *)vp2; return ( memcmp(&t1->vertices[0],&t2->vertices[0],3*sizeof(tpoint*)) ); } #define STATICNNEIG 16 #define LISTBLOCK 32 int expand_triangulation(triinfo *ti,triangle **rtris,int *rntri,tpoint *points,int npoint,int level) { triangle *tris,*wtris; int ntri,nwtri,atri,i,j,k,l,m,p,a,b,c; int *ngs,nng,ang,nng0,nng1; tpoint **tn; if ( ti==NULL || points==NULL ) return(1); atri=LISTBLOCK; tris=(triangle *)malloc(sizeof(triangle)*atri); ntri=0; ang=LISTBLOCK; ngs=(int *)malloc(sizeof(int)*ang); for ( i=0 ; ineigs[i]; nng=0; for ( j=0 ; tn[j] != NULL ; j++ ) { k=tn[j]-points; /*if ( k<=i ) continue;*/ if ( nng>=ang ) { ang+=LISTBLOCK; ngs=(int *)realloc(ngs,sizeof(int)*ang); } ngs[nng]=k; nng++; } nng0=0; for ( l=1 ; lneigs[ngs[m]]; for ( j=0 ; tn[j] != NULL ; j++ ) { k=tn[j]-points; if ( k<=i ) continue; for ( p=0 ; p=ang ) { ang+=LISTBLOCK; ngs=(int *)realloc(ngs,sizeof(int)*ang); } ngs[nng]=k; nng++; } } nng0=nng1; } for ( k=0 ; k=i ) continue;*/ for ( l=0 ; l=atri ) { atri+=LISTBLOCK; tris=(triangle *)realloc(tris,sizeof(triangle)*atri); } a=i, b=ngs[k]; c=ngs[l]; if ( a>b ) p=a,a=b,b=p; if ( b>c ) p=b,b=c,c=p; if ( a>b ) p=a,a=b,b=p; tris[ntri].vertices[0]=points+a; tris[ntri].vertices[1]=points+b; tris[ntri].vertices[2]=points+c; ntri++; } } } qsort(tris,ntri,sizeof(triangle),compare_triangle_vertices); wtris=(triangle *)malloc(sizeof(triangle)*atri); memcpy(&wtris[0],&tris[0],sizeof(triangle)); nwtri=1; for ( i=1 ; i #include #include #include "point.h" #include "fit/lmfit.h" #include "splinefit.h" #define RECIP6 (1.0/6.0) /*****************************************************************************/ static int basespline_coeff(int n,int c,double *y2,double *tmp) { int i; double p,qn,un,*u; u=tmp; y2[0]=u[0]=0.0; for ( i=1 ; i=0 ; i-- ) { y2[i]=y2[i]*y2[i+1]+u[i]; } return(0); } /*****************************************************************************/ int fit_1d_spline(double x0,double x1,int nx, double *xv,double *yv,int npoint,double *wv,double *coeff) { int nvar,i,j,k,t; double **splinebase,*tmp; double **amatrix,*bvector,*fvars,x,y,a,b,w; double yl,yr,y2l,y2r,c2l,c2r; nvar=nx+1; if ( x0==x1 ) return(-1); else if ( x0>x1 ) x=x0,x0=x1,x1=x; if ( xv==NULL || yv==NULL ) return(-1); if ( npoint=x1 ) continue; t=(int)floor((double)nx*(x-x0)/(x1-x0)); b=(double)nx*(x-x0)/(x1-x0)-(double)t; a=1.0-b; c2l=(a*a*a-a)*RECIP6; c2r=(b*b*b-b)*RECIP6; for ( i=0 ; i<=nx ; i++ ) { if ( i==t+0 ) yl=1.0,yr=0.0; else if ( i==t+1 ) yl=0.0,yr=1.0; else yl=0.0,yr=0.0; y2l=splinebase[i][t+0]; y2r=splinebase[i][t+1]; fvars[i]=a*yl+b*yr+c2l*y2l+c2r*y2r; } if ( wv == NULL ) w=1.0; else w=wv[k]; for ( i=0 ;ix1 ) x=x0,x0=x1,x1=x; if ( y0==y1 ) return(-1); else if ( y0>y1 ) y=y0,y0=y1,y1=y; if ( points==NULL ) return(-1); nvar=(nx+1)*(ny+1); if ( npointny?nx:ny)+1; splinexbase=matrix_alloc(nx+1); splineybase=matrix_alloc(ny+1); tmp=vector_alloc(mx); for ( i=0 ; i<=nx ; i++ ) { basespline_coeff(nx+1,i,splinexbase[i],tmp); } for ( i=0 ; i<=ny ; i++ ) { basespline_coeff(ny+1,i,splineybase[i],tmp); } vector_free(tmp); amatrix=matrix_alloc(nvar); bvector=vector_alloc(nvar); fvars =vector_alloc(nvar); zvsx=(double *)malloc(sizeof(double)*(nx+1)); zvsy=(double *)malloc(sizeof(double)*(ny+1)); for ( i=0 ; i #include #include #include #include "intersec.h" int intersec_rectangles(drectangle *r1,drectangle *r2,drectangle *ir) { double p1,l1,p2,l2,p,l; ir->x=ir->y=ir->sx=ir->sy=0.0; p1=r1->x,l1=r1->sx, p2=r2->x,l2=r2->sx; if ( fabs((2*p1+l1)-(2*p2+l2)) >= l1+l2 ) return(1); if ( p2>p1 ) { p=p2;l=p1+l1-p2;if ( l2x=p,ir->sx=l; p1=r1->y,l1=r1->sy, p2=r2->y,l2=r2->sy; if ( fabs((2*p1+l1)-(2*p2+l2)) >= l1+l2 ) return(1); if ( p2>p1 ) { p=p2;l=p1+l1-p2;if ( l2y=p,ir->sy=l; return(0); } double area_rectangle(drectangle *r) { double a; a=r->sx*r->sy; return(a); } double area_circle(dcircle *c) { double a; a=M_PI*(c->radius)*(c->radius); return(a); } /* The indefinite integral of \sqrt{r^2-x^2}... */ static double area_indefinite(double r,double x) { double t,w; if ( x<=-r ) return(0.5*r*r*asin(-1.0)); else if ( x>=r ) return(0.5*r*r*asin(+1.0)); t=x/r; w=0.5*r*r*(asin(t)+t*sqrt(1.0-t*t)); return(w); } static double area_intersec_of_rect_semic(double cx,double cy,double r,double by,double sy,double x1,double x2) { double dx1,dx2,s,w,a; if ( x1==x2 ) return(0.0); else if ( x1>x2 ) w=x1,x1=x2,x2=w; if ( sy==0.0 ) return(0.0); else if ( sy<0 ) by+=sy,sy=-sy; if ( cy+r<=by || by+sy<=cy ) return(0.0); if ( by=cy+r ) { if ( by==cy ) dx1=cx-r,dx2=cx+r,s=0.0; else s=by-cy,w=sqrt(r*r-s*s),dx1=cx-w,dx2=cx+w; if ( x2<=dx1 || x1>=dx2 ) return(0.0); if ( x1dx2 ) x2=dx2; a=area_indefinite(r,x2-cx)-area_indefinite(r,x1-cx)-s*(x2-x1); return(a); } else { double hs,hx1,hx2,hdx1,hdx2,a1,a2; if ( by==cy ) dx1=cx-r,dx2=cx+r,s=0.0; else s=by-cy,w=sqrt(r*r-s*s),dx1=cx-w,dx2=cx+w; if ( x2<=dx1 || x1>=dx2 ) return(0.0); if ( x1dx2 ) x2=dx2; hs=by+sy-cy;w=sqrt(r*r-hs*hs);hdx1=cx-w,hdx2=cx+w; hx1=x1,hx2=x2; if ( hx1hdx2 ) hx2=hdx2; if ( hx1x,+c->y,c->radius,+r->y,r->sy,r->x,r->x+r->sx); alower=area_intersec_of_rect_semic(c->x,-c->y,c->radius,-r->y-r->sy,r->sy,r->x,r->x+r->sx); return(aupper+alower); } /*****************************************************************************/ fitsh-0.9.2/src/math/intersec/intersec-cri.c0000644000175000017500000001341412771507673017364 0ustar apalapal/*****************************************************************************/ /* intersec-cri.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for integrating polynomials surfaces on intersections */ /* of circles and rectangles. */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in intersec-cri.h */ /*****************************************************************************/ #include #include #include #include #include "intersec-cri.h" /*****************************************************************************/ static int intersec_cri_int_indefinite(double *pc,int order,double mul, double r,double x) { double t,s,c; double r2,r3,r4; double c2,s2,c4,sc; s=x/r; if ( s<-1.0 ) s=-1.0; if ( s>+1.0 ) s=+1.0; t=asin(s);c=cos(t); c2=c*c,s2=s*s,c4=c2*c2,sc=s*c; r2=r*r,r3=r2*r,r4=r2*r2; switch ( order ) { case 2: pc[3]+=mul*r4*0.125*(t+sc*(s2-c2)); /* x^2 */ pc[4]-=mul*r4*0.125*c4; /* xy */ pc[5]+=mul*r4*(3*t+sc*(2.0*c2+3.0))/24.0; /* y^2 */ case 1: pc[1]-=mul*r3*(c2*c)/3.0; /* x */ pc[2]+=mul*r3*s*(0.5-s2/6.0); /* y */ case 0: pc[0]+=mul*r2*0.5*(t+sc); /* 1 */ break; } return(0); } static int intersec_cri_int_semirect_definite(double *pc,int order,double mul, double x1,double x2,double y2) { double w,sx,sx2,sy,sy2; sx=x2+x1,sx2=x2*sx+x1*x1;sx=sx/2.0,sx2=sx2/3.0; sy=y2 ,sy2=y2*sy ;sy=sy/2.0,sy2=sy2/3.0; w=(x2-x1)*y2*mul; switch ( order ) { case 2: pc[3]+=w*sx2; /* x^2 */ pc[4]+=w*sx*sy; /* xy */ pc[5]+=w*sy2; /* y^2 */ case 1: pc[1]+=w*sx; /* x */ pc[2]+=w*sy; /* y */ case 0: pc[0]+=w; /* 1 */ break; } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int intersec_cri_int_semicircle(double *pc,int order, double x1,double x2,double y1,double y2,double r) { double by,sy,dx1,dx2,s,w; by=y1; sy=y2-y1; if ( r<=by || by+sy<=0 ) return(0); if ( by<0.0 ) sy+=by,by=0.0; if ( sy<=0.0 ) return(0); if ( by+sy>=r ) { if ( by==0.0 ) dx1=-r,dx2=+r,s=0.0; else s=by,w=sqrt(r*r-s*s),dx1=-w,dx2=+w; if ( x2<=dx1 || x1>=dx2 ) return(0); if ( x1dx2 ) x2=dx2; intersec_cri_int_indefinite(pc,order,+1,r,x2); intersec_cri_int_indefinite(pc,order,-1,r,x1); intersec_cri_int_semirect_definite(pc,order,-1,x1,x2,by); return(0); } else { double hs,hx1,hx2,hdx1,hdx2; if ( by==0.0 ) dx1=-r,dx2=+r,s=0.0; else s=by,w=sqrt(r*r-s*s),dx1=-w,dx2=+w; if ( x2<=dx1 || x1>=dx2 ) return(0); if ( x1dx2 ) x2=dx2; hs=by+sy;w=sqrt(r*r-hs*hs);hdx1=-w,hdx2=+w; hx1=x1,hx2=x2; if ( hx1hdx2 ) hx2=hdx2; if ( hx12 ) order=2; nvar=(order+1)*(order+2)/2; for ( i=0 ; i= hdiam + cr ) return(0); /* The rectangle is contained by the circle: */ if ( cr >= hdiam + cdis ) { switch ( order ) { case 2: coeff[3]=sy*sx*(x0*x0+x0*sx+sx*sx/3.0); coeff[4]=sx*(x0+0.5*sx)*sy*(y0+0.5*sy); coeff[5]=sx*sy*(y0*y0+y0*sy+sy*sy/3.0); case 1: coeff[1]=sy*sx*(x0+0.5*sx); coeff[2]=sx*sy*(y0+0.5*sy); case 0: coeff[0]=sx*sy; break; } } /* Shift the polynomial coefficients to set the center of the circle to 0: */ /* acf[0]=pcf[0]+cx*(pcf[1]+cx*pcf[2])+ cy*((pcf[3]+cx*(pcf[4]+cx*pcf[5]))+ cy*(pcf[6]+cx*(pcf[7]+cx*pcf[8]))); acf[1]=pcf[1]+2*cx*pcf[2]+cy*((pcf[4]+2*cx*pcf[5])+cy*(pcf[7]+2*cx*pcf[8])); acf[2]=pcf[2]+cy*(pcf[5]+cy*pcf[8]); acf[3]=pcf[3]+cx*(pcf[4]+cx*pcf[5])+2*cy*(pcf[6]+cx*(pcf[7]+cx*pcf[8])); acf[4]=pcf[4]+2*cx*pcf[5]+2*cy*(pcf[7]+2*cx*pcf[8]); acf[5]=pcf[5]+2*cy*pcf[8]; acf[6]=pcf[6]+cx*(pcf[7]+cx*pcf[8]); acf[7]=pcf[7]+2*cx*pcf[8]; acf[8]=pcf[8]; */ for ( i=0 ; i #include "spmatrix.h" /* this is a node in a sparse matrix */ typedef struct node { int row,col; /* position in the matrix */ int value; /* the integer value of the node */ struct node * next_in_row; struct node * next_in_col; } node; /* a 2D sparse matrix */ typedef struct { node *elements; int rows, cols; int count; /* how many elements in the matrix */ sperr err; node *rwitness; node *cwitness; } sparse_matrix; /* local functions to manipulate internal structures */ static void set_elem(node *this, int row, int col, int value, node *nextrow, node *nextcol) { if ( this != NULL ) { this->row = row; this->col = col; this->value = value; this->next_in_row = nextrow; this->next_in_col = nextcol; } return; } static node *new_elem(int row,int col,int val,node *nextrow,node *nextcol) { node *new=malloc(sizeof *new); if ( new != NULL ) set_elem(new, row, col, val, nextrow, nextcol); return(new); } static node *find_node(sparse_matrix *sm,int row,int col) { node *header,*tmp,*nptr; if ( row > sm->rows || col > sm->cols ) return(NULL); header = sm->elements; if ( col > row ) { nptr = row >= sm->rwitness->row ? sm->rwitness : header; while ( nptr->row < row ) nptr = nptr->next_in_col; tmp = nptr->next_in_row; while ( tmp != nptr && tmp->col < col ) tmp = tmp->next_in_row; if ( tmp->col == col ) return(tmp); } else { nptr = (col >= sm->cwitness->col ? sm->cwitness : header); while ( nptr->col < col ) nptr = nptr->next_in_row; if ( !row ) return(nptr); tmp = nptr->next_in_col; while ( tmp != nptr && tmp->row < row ) tmp = tmp->next_in_col; if(tmp->row == row) return(tmp); } return(NULL); } /* create an empty sparse matrix */ spmatrix *spm_create(void) { node *head; sparse_matrix *sm; spmatrix *sm_cont=NULL; if ( (sm=malloc(sizeof *sm)) == NULL || (sm_cont=malloc(sizeof *sm_cont)) == NULL || (head=malloc(sizeof *head)) == NULL ) { free(sm); free(sm_cont); return(NULL); } set_elem(head,0,0,0,head,head); sm->elements=head; sm->rows =0; sm->cols =0; sm->count =1; /* head is the first element */ sm->err =SpNoErr; sm->rwitness=head; sm->cwitness=head; sm_cont->matrix=(void *) sm; return(sm_cont); } /* clean up a sparse matrix */ void spm_destroy(spmatrix *spm) { sparse_matrix *sm; node *nd,*nd_next,*header,*first; int count; if ( spm==NULL ) return; sm =(sparse_matrix *) (spm->matrix); header =sm->elements; count =sm->count; first =header; nd_next=header->next_in_row; do { nd = nd_next; if ( nd==first ) { nd_next = first->next_in_col; if ( first != header ) free(first); first = nd_next; nd_next = first->next_in_row; } else { nd_next = nd->next_in_row; free(nd); } } while(--count); free(header); free(sm); free(spm); return; } /* get error status of a sparse matrix */ sperr spm_geterr(spmatrix *sm) { if ( sm == NULL ) return(SpNull); else return(((sparse_matrix *)(sm->matrix))->err); } /* get number of elements in the sparse matrix */ int spm_numofelems(spmatrix *sm) { if ( sm == NULL ) return(0); else return(((sparse_matrix *)(sm->matrix))->count); } /* set a node value. if it does not exist, create it */ void spm_setnode(spmatrix *spm,int row,int col,int value) { node *nd = NULL; sparse_matrix *sm; if ( spm == NULL ) return; sm=(sparse_matrix *) spm->matrix; if ( row<0 || col<0 ) { sm->err = SpInvSub; return; } /* try to find the node */ if ( col <= sm->cols && row <= sm->rows ) nd = find_node(sm, row, col); /* create a new node and set its value */ if ( nd == NULL ) { node *prevrow, *prevcol, *tmp; node *new = NULL, *colptr = NULL, *rowptr = NULL; if ( col > sm->cols ) { int ii,ccol; node *befptr=find_node(sm, 0, sm->cols); for ( ii=sm->cols+1 ; ii<=col ; ii++ ) { if ( (new=malloc(sizeof *new)) == NULL ) { sm->err = SpMem; return; } set_elem(new, 0, ii, 0, sm->elements, new); befptr->next_in_row = new; befptr = new; (sm->count)++; } colptr = new; sm->cols = col; /* set witness */ ccol = col/2; while ( sm->cwitness->colcwitness = sm->cwitness->next_in_row; } if ( row > sm->rows ) { int ii,rrow; node *befptr=find_node(sm, sm->rows, 0); for ( ii=sm->rows+1 ; ii <= row ; ii++ ) { if ( (new = malloc(sizeof *new)) == NULL ) { sm->err = SpMem; return; } set_elem(new, ii, 0, 0, new, sm->elements); befptr->next_in_col = new; befptr = new; (sm->count)++; } rowptr = new; sm->rows = row; /* set witness */ rrow = row/2; while ( sm->rwitness->rowrwitness = sm->rwitness->next_in_col; } if ( ! row ) /* colptr already pointing to required node */ (colptr->value)++; else if ( ! col ) /* rowptr already pointing to required node */ (rowptr->value)++; else /* find the column into which the new element will be inserted */ { if ( colptr == NULL ) colptr = find_node(sm, 0, col); prevcol = colptr; tmp = prevcol->next_in_col; while ( tmp != colptr && tmp->rownext_in_col; } /* find the row into which the new element will be inserted */ if ( rowptr == NULL ) rowptr = find_node(sm, row, 0); prevrow = rowptr; tmp = prevrow->next_in_row; while ( tmp != rowptr && tmp->colnext_in_row; } new=new_elem(row,col,1,prevrow->next_in_row, prevcol->next_in_col); if ( new == NULL ) { sm->err = SpMem; return; } prevcol->next_in_col = new; prevrow->next_in_row = new; (sm->count)++; } } else /* the node is already there: simply set its value */ nd->value = value; return; } /* increase a node value by 1. if it does not exist, create it */ void spm_incrnode(spmatrix *spm,int row,int col) { node *nd=NULL; sparse_matrix *sm; if ( spm == NULL ) return; sm=(sparse_matrix *) spm->matrix; if ( row<0 || col<0 ) { sm->err = SpInvSub; return; } /* try to find the node */ if ( col<=sm->cols && row<=sm->rows ) nd = find_node(sm, row, col); /* create a new node and set its value */ if ( nd == NULL ) { node *prevrow, *prevcol, *tmp; node *new = NULL, *colptr = NULL, *rowptr = NULL; if ( col > sm->cols ) { int ii, ccol; node *befptr = find_node(sm, 0, sm->cols); for ( ii=sm->cols+1 ; ii<=col ; ii++ ) { if ( (new = malloc(sizeof *new)) == NULL ) { sm->err = SpMem; return; } set_elem(new, 0, ii, 0, sm->elements, new); befptr->next_in_row = new; befptr = new; (sm->count)++; } colptr = new; sm->cols = col; /* set witness */ ccol = col/2; while ( sm->cwitness->colcwitness = sm->cwitness->next_in_row; } if ( row>sm->rows ) { int ii, rrow; node *befptr = find_node(sm, sm->rows, 0); for ( ii=sm->rows+1 ; ii <= row ; ii++ ) { if ( (new = malloc(sizeof *new)) == NULL ) { sm->err = SpMem; return; } set_elem(new, ii, 0, 0, new, sm->elements); befptr->next_in_col = new; befptr = new; (sm->count)++; } rowptr = new; sm->rows = row; /* set witness */ rrow = row/2; while ( sm->rwitness->rowrwitness = sm->rwitness->next_in_col; } if ( ! row ) /* colptr already pointing to required node */ (colptr->value)++; else if ( ! col ) /* rowptr already pointing to required node */ (rowptr->value)++; else /* find the column into which the new element will be inserted */ { if ( colptr == NULL ) colptr = find_node(sm, 0, col); prevcol = colptr; tmp = prevcol->next_in_col; while ( tmp != colptr && tmp->row < row ) { prevcol = tmp; tmp = tmp->next_in_col; } /* find the row into which the new element will be inserted */ if(rowptr == NULL) rowptr = find_node(sm, row, 0); prevrow = rowptr; tmp = prevrow->next_in_row; while ( tmp != rowptr && tmp->col < col ) { prevrow = tmp; tmp = tmp->next_in_row; } new=new_elem(row,col,1,prevrow->next_in_row, prevcol->next_in_col); if ( new == NULL ) { sm->err = SpMem; return; } prevcol->next_in_col = new; prevrow->next_in_row = new; (sm->count)++; } } else /* the node is already there: simply set its value */ (nd->value)++; return; } /* increase a node value by the given value. if it does not exist, create it */ void spm_addval(spmatrix *spm, int val, int row, int col) { node *nd = NULL; sparse_matrix *sm; if ( spm == NULL ) return; sm=(sparse_matrix *) spm->matrix; if ( row<0 || col < 0 ) { sm->err = SpInvSub; return; } /* try to find the node */ if ( col <= sm->cols && row <= sm->rows ) nd = find_node(sm, row, col); /* create a new node and set its value */ if ( nd == NULL ) { node *prevrow, *prevcol, *tmp; node *new = NULL, *colptr = NULL, *rowptr = NULL; if ( col > sm->cols ) { int ii, ccol; node *befptr=find_node(sm, 0, sm->cols); for ( ii=sm->cols+1 ; ii <= col ; ii++ ) { if ( (new = malloc(sizeof *new)) == NULL ) { sm->err = SpMem; return; } set_elem(new, 0, ii, 0, sm->elements, new); befptr->next_in_row = new; befptr = new; (sm->count)++; } colptr = new; sm->cols = col; /* set witness */ ccol = col/2; while ( sm->cwitness->col < ccol ) sm->cwitness = sm->cwitness->next_in_row; } if ( row > sm->rows ) { int ii,rrow; node *befptr = find_node(sm, sm->rows, 0); for(ii = sm->rows + 1; ii <= row; ii++) { if ( (new = malloc(sizeof *new)) == NULL ) { sm->err = SpMem; return; } set_elem(new, ii, 0, 0, new, sm->elements); befptr->next_in_col = new; befptr = new; (sm->count)++; } rowptr = new; sm->rows = row; /* set witness */ rrow = row/2; while ( sm->rwitness->row < rrow ) sm->rwitness = sm->rwitness->next_in_col; } if ( ! row ) /* colptr already pointing to required node */ colptr->value += val; else if ( ! col ) /* rowptr already pointing to required node */ rowptr->value += val; else /* find the column into which the new element will be inserted */ { if ( colptr == NULL ) colptr = find_node(sm, 0, col); prevcol = colptr; tmp = prevcol->next_in_col; while ( tmp != colptr && tmp->row < row ) { prevcol = tmp; tmp = tmp->next_in_col; } /* find the row into which the new element will be inserted */ if ( rowptr == NULL ) rowptr = find_node(sm, row, 0); prevrow = rowptr; tmp = prevrow->next_in_row; while ( tmp != rowptr && tmp->col < col ) { prevrow = tmp; tmp = tmp->next_in_row; } new=new_elem(row,col,val,prevrow->next_in_row,prevcol->next_in_col); if ( new == NULL ) { sm->err = SpMem; return; } prevcol->next_in_col = new; prevrow->next_in_row = new; (sm->count)++; } } else /* the node is already there: simply set its value */ nd->value += val; return; } /* return the value of a node */ int spm_getval(spmatrix *sm,int row,int col) { node *nd; if ( sm == NULL || row < 0 || col < 0 ) return(0); nd=find_node((sparse_matrix *) (sm->matrix),row,col); return(nd==NULL ? 0:nd->value); } /* return a node or NULL */ spnode spm_getnode(spmatrix *spm, int row, int col) { if ( spm == NULL || row < 0 || col < 0 ) return(NULL); else return((spnode)find_node((sparse_matrix *)(spm->matrix),row,col)); } /* get next non-zero value from the sparse-matrix */ spnode spm_getnextnode(spmatrix *spm, spnode snd, spnode *witness) { node *header, *nd, *first; sparse_matrix *sm; if ( spm == NULL ) return(NULL); sm =(sparse_matrix *)(spm->matrix); header=sm->elements; if ( snd == NULL ) { nd = header; first = header; *witness = (spnode) header; if ( header->value != 0 ) return((spnode) header); } else { nd = (node *) snd; first = (node *) *witness; } do { nd = nd->next_in_row; if ( nd==first ) { first = first->next_in_col; /* no more elements left */ if ( first == header ) return NULL; nd = first; *witness = (spnode) first; } if(nd->value) return((spnode)nd); } while(nd != header); return(NULL); } /* returns column number of a node */ int spm_getcol(spnode snd) { if ( snd == NULL ) return(-1); else return(((node *) snd)->col); } /* returns row number of a node */ int spm_getrow(spnode snd) { if ( snd == NULL ) return(-1); else return(((node *) snd)->row); } /* returns value of a node */ int spm_getnodeval(spnode snd) { if ( snd == NULL ) return(0); else return(((node *) snd)->value); } /* set a node's value */ void spm_setnodeval(spnode snd, int value) { if ( snd == NULL ) return; ((node *) snd)->value = value; return; } fitsh-0.9.2/src/math/polyfit.h0000644000175000017500000000355411001721556014637 0ustar apalapal/*****************************************************************************/ /* polyfit.h */ /*****************************************************************************/ #ifndef __POLYFIT_H_INCLUDED #define __POLYFIT_H_INCLUDED 1 #include "point.h" #include "poly.h" /* fit_2d_poly(): Fits a 2 dimensional polynomial up to order 'order' to the points 'dat'. The number of the points 'nd' should be greater or equal than the number of monomials to the order 'order': nd >= (order+1)*(order+2)/2, (1) otherwise the fit cannot be performed (the least-squares matrix will be singular). Before the fit, all points are shifted and scaled using the parameters 'ox', 'oy' and 'scale'. If the fit was successful, the coefficients of the fitted polynomial is retured in the array 'fit' and 0 is returned. If the allocation of the temporary resources fails, the function returns a negative value. If the fit cannot be performed because there are not enough points (so, (1) is not satisfied) or the least-squares matrix is singular, the function returns a positive value. */ int fit_2d_poly ( point *dat,int nd,int order,double *fit, double ox,double oy,double scale); /* fit_2d_leg_poly(): Fits a 2 dimensional Legendre polynomial up to order 'order' to the points 'dat'. See also fit_2d_poly(). */ int fit_2d_leg_poly(point *dat,int nd,int order,double *fit, double ox,double oy,double scale); /* fit_1d_poly(): Fits an 1 dimensional non-normalized polynomial up to order 'order' to the points (x,y)[]. The number of points is 'nd'. The fitted coefficients are returned in 'coeff' (order+1 values). If nd is less or equal than order, the fit is not performed and the function returns a non-zero value.*/ int fit_1d_poly(int order,double *x,double *y,int nd,double *w,double *coeff); #endif fitsh-0.9.2/src/math/elliptic/0000755000175000017500000000000012772016355014610 5ustar apalapalfitsh-0.9.2/src/math/elliptic/elliptic.h0000644000175000017500000000175010776035321016565 0ustar apalapal/*****************************************************************************/ /* elliptic.h */ /*****************************************************************************/ #ifndef __ELLIPTIC_H_INCLUDED #define __ELLIPTIC_H_INCLUDED 1 /*****************************************************************************/ double carlson_elliptic_rc(double x,double y); double carlson_elliptic_rf(double x,double y,double z); double carlson_elliptic_rd(double x,double y,double z); double carlson_elliptic_rj(double x,double y,double z,double p); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ double elliptic_complete_first(double k); double elliptic_complete_second(double k); double elliptic_complete_third(double n,double k); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/math/elliptic/ntiq.h0000644000175000017500000000127411002463770015730 0ustar apalapal/*****************************************************************************/ /* ntiq.h */ /*****************************************************************************/ #ifndef __NTIQ_H_INCLUDED #define __NTIQ_H_INCLUDED 1 /*****************************************************************************/ double ntiq(double p,double z,double g1,double g2); double ntiq_diff(double p,double z,double g1,double g2,double *diff); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/math/elliptic/ntiq.c0000644000175000017500000003441012117314405015717 0ustar apalapal/*****************************************************************************/ /* ntiq.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to the calculations of obscured stellar flux taking */ /* into account quadratic limb darkening. These functions also provide the */ /* parametric partial derivatives of the obscuring function. A bit redundant */ /* coding, however, straight and hopefully clean. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* If you use these code in your research, please cite astro-ph:0805.2157, */ /* and if you are using the flux decrease itself (i.e. not only the partial */ /* derivatives), please cite 2002, ApJ, 580, 171 too. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2007; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include "elliptic.h" #include "ntiq.h" /*****************************************************************************/ #define SMALL (1e-13) /*****************************************************************************/ #ifndef M_PI #define M_PI 3.1415926535897932384626433832795028841968 #endif /*****************************************************************************/ double ntiq(double p,double z,double g1,double g2) { double w0,w1,w2; double f0,f1,fk,fe,fp,f2,n,k; double df; w0=(6-6*g1-12*g2)/(6-2*g1-g2); w1=( 6*g1+12*g2 )/(6-2*g1-g2); w2=( 6*g2 )/(6-2*g1-g2); z=fabs(z); if ( z<=0.0 && p<=1.0 ) /* A */ /* M&A 10 */ { f0=p*p; f1=2.0/3.0*(1.0-(1.0-f0)*sqrt(1.0-f0)); fk=fe=fp=0.0; f2=0.5*f0*f0; k=n=0.0; } else if ( z<=p-1.0 ) /* A_G */ /* M&A 11 */ { f0=1.0; fk=fe=fp=0.0; f1=2.0/3.0; f2=0.5; k=n=0.0; } else if ( z

#include #include #include "elliptic.h" /*****************************************************************************/ #define FMIN(a,b) ((a)<(b)?(a):(b)) #define FMAX(a,b) ((a)<(b)?(a):(b)) #define SQR(a) ((a)*(a)) #define C1 0.3 #define C2 (1.0/7.0) #define C3 0.375 #define C4 (9.0/22.0) double carlson_elliptic_rc(double x,double y) { double alamb,ave,s,w,xt,yt,ans; if ( y > 0.0 ) { xt=x; yt=y; w=1.0; } else { xt=x-y; yt = -y; w=sqrt(x)/sqrt(xt); } do { alamb=2.0*sqrt(xt)*sqrt(yt)+yt; xt=0.25*(xt+alamb); yt=0.25*(yt+alamb); ave=(1.0/3.0)*(xt+yt+yt); s=(yt-ave)/ave; } while ( fabs(s) > 0.0012 ); ans=w*(1.0+s*s*(C1+s*(C2+s*(C3+s*C4))))/sqrt(ave); return(ans); } #undef C4 #undef C3 #undef C2 #undef C1 double carlson_elliptic_rf(double x,double y,double z) { double alamb,ave,delx,dely,delz,e2,e3,sqrtx,sqrty,sqrtz,xt,yt,zt; xt=x; yt=y; zt=z; do { sqrtx=sqrt(xt); sqrty=sqrt(yt); sqrtz=sqrt(zt); alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz; xt=0.25*(xt+alamb); yt=0.25*(yt+alamb); zt=0.25*(zt+alamb); ave=(1.0/3.0)*(xt+yt+zt); delx=(ave-xt)/ave; dely=(ave-yt)/ave; delz=(ave-zt)/ave; } while ( fabs(delx) > 0.0025 || fabs(dely) > 0.0025 || fabs(delz) > 0.0025 ); e2=delx*dely-delz*delz; e3=delx*dely*delz; return((1.0+((1.0/24.0)*e2-(0.1)-(3.0/44.0)*e3)*e2+(1.0/14.0)*e3)/sqrt(ave)); } #define C1 (3.0/14.0) #define C2 (1.0/6.0) #define C3 (9.0/22.0) #define C4 (3.0/26.0) #define C5 (0.25*C3) #define C6 (1.5*C4) double carlson_elliptic_rd(double x,double y,double z) { double alamb,ave,delx,dely,delz,ea,eb,ec,ed,ee,fac, sqrtx,sqrty,sqrtz,sum,xt,yt,zt,ans; xt=x; yt=y; zt=z; sum=0.0; fac=1.0; do { sqrtx=sqrt(xt); sqrty=sqrt(yt); sqrtz=sqrt(zt); alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz; sum+=fac/(sqrtz*(zt+alamb)); fac=0.25*fac; xt=0.25*(xt+alamb); yt=0.25*(yt+alamb); zt=0.25*(zt+alamb); ave=0.2*(xt+yt+3.0*zt); delx=(ave-xt)/ave; dely=(ave-yt)/ave; delz=(ave-zt)/ave; } while ( fabs(delx) > 0.0015 || fabs(dely) > 0.0015 || fabs(delz) > 0.0015 ); ea=delx*dely; eb=delz*delz; ec=ea-eb; ed=ea-6.0*eb; ee=ed+ec+ec; ans=3.0*sum+fac*(1.0+ed*(-C1+C5*ed-C6*delz*ee) +delz*(C2*ee+delz*(-C3*ec+delz*C4*ea)))/(ave*sqrt(ave)); return(ans); } #undef C6 #undef C5 #undef C4 #undef C3 #undef C2 #undef C1 #define C1 (3.0/14.0) #define C2 (1.0/3.0) #define C3 (3.0/22.0) #define C4 (3.0/26.0) #define C5 (0.75*C3) #define C6 (1.5*C4) #define C7 (0.5*C2) #define C8 (C3+C3) double carlson_elliptic_rj(double x,double y,double z,double p) { double a,alamb,alpha,ans,ave,b,beta,delp,delx,dely,delz,ea,eb,ec, ed,ee,fac,pt,rcx,rho,sqrtx,sqrty,sqrtz,sum,tau,xt,yt,zt; sum=0.0; fac=1.0; if ( p > 0.0 ) { xt=x; yt=y; zt=z; pt=p; a=b=rcx=0.0; } else { xt=FMIN(FMIN(x,y),z); zt=FMAX(FMAX(x,y),z); yt=x+y+z-xt-zt; a=1.0/(yt-p); b=a*(zt-yt)*(yt-xt); pt=yt+b; rho=xt*zt/yt; tau=p*pt/yt; rcx=carlson_elliptic_rc(rho,tau); } do { sqrtx=sqrt(xt); sqrty=sqrt(yt); sqrtz=sqrt(zt); alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz; alpha=SQR(pt*(sqrtx+sqrty+sqrtz)+sqrtx*sqrty*sqrtz); beta=pt*SQR(pt+alamb); sum += fac*carlson_elliptic_rc(alpha,beta); fac=0.25*fac; xt=0.25*(xt+alamb); yt=0.25*(yt+alamb); zt=0.25*(zt+alamb); pt=0.25*(pt+alamb); ave=0.2*(xt+yt+zt+pt+pt); delx=(ave-xt)/ave; dely=(ave-yt)/ave; delz=(ave-zt)/ave; delp=(ave-pt)/ave; } while ( fabs(delx)>0.0015 || fabs(dely)>0.0015 || fabs(delz)>0.0015 || fabs(delp)>0.0015 ); ea=delx*(dely+delz)+dely*delz; eb=delx*dely*delz; ec=delp*delp; ed=ea-3.0*ec; ee=eb+2.0*delp*(ea-ec); ans=3.0*sum+fac*(1.0+ed*(-C1+C5*ed-C6*ee)+eb*(C7+delp*(-C8+delp*C4)) +delp*ea*(C2-delp*C3)-C2*delp*ec)/(ave*sqrt(ave)); if ( p <= 0.0 ) ans=a*(b*ans+3.0*(rcx-carlson_elliptic_rf(xt,yt,zt))); return(ans); } #undef C6 #undef C5 #undef C4 #undef C3 #undef C2 #undef C1 #undef C8 #undef C7 #undef SQR #undef FMAX #undef FMIN /*****************************************************************************/ double elliptic_complete_first(double ak) { double q; q=(1.0-ak)*(1.0+ak); if ( q>0.0 ) return(carlson_elliptic_rf(0.0,q,1.0)); else return(-1.0); } double elliptic_complete_second(double ak) { double q; q=(1.0-ak)*(1.0+ak); if ( q>0.0 ) return(carlson_elliptic_rf(0.0,q,1.0)-(ak*ak)*carlson_elliptic_rd(0.0,q,1.0)/3.0); else if ( q<0.0 ) return(-1.0); else return(1.0); } double elliptic_complete_third(double en,double ak) { double q; q=(1.0-ak)*(1.0+ak); if ( q>0.0 ) return(carlson_elliptic_rf(0.0,q,1.0)+en*carlson_elliptic_rj(0.0,q,1.0,1.0-en)/3.0); else return(-1.0); } /*****************************************************************************/ fitsh-0.9.2/src/math/poly.c0000644000175000017500000001454411116251777014142 0ustar apalapal/*****************************************************************************/ /* poly.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for evaluating polynomials (standard and Legendre) */ /* defined in R^2 (in a plane). */ /* (c) 2001, 2004, 2005, 2006; Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in poly.h */ /*****************************************************************************/ #include #include #include #include #include "poly.h" /*****************************************************************************/ int eval_2d_monoms(double x,double y,int order,double *ret,double ox,double oy,double scale) { int i,j,k,n; x=(x-ox)/scale; y=(y-oy)/scale; switch ( order ) { case 0: ret[0]=1.0; break; case 1: ret[0]=1.0; ret[1]=x;ret[2]=y; break; default: ret[0]=1.0; for ( i=0,k=0 ; k=0 ) { i=n;p=m;w=coeff[m];k=order; while ( i>=1 ) { w=w*x/(double)i; p-=k; w+=coeff[p]; i--;k--; }; ret+=w*ym; ym=ym*y/(double)yf; yf++; n--,m++; }; return(ret); } } /*****************************************************************************/ int eval_2d_leg_monoms(double x,double y,int order,double *ret,double ox,double oy,double scale) { int i,j,k,n,p1,p2; x=(x-ox)/scale; y=(y-oy)/scale; switch ( order ) { case 0: ret[0]=1.0; break; case 1: ret[0]=1.0; ret[1]=x,ret[2]=y; break; default: ret[0]=1.0; ret[1]=x,ret[2]=y; for ( k=1,p1=0,p2=1,n=3 ; k=2 ) { ma=xfit[1],mb=xfit[2]; mc=yfit[1],md=yfit[2]; det=ma*md-mb*mc; dx=(-xfit[0]*md+yfit[0]*mb)/det; dy=(-ma*yfit[0]+mc*xfit[0])/det; if ( det==0.0 ) { return(-1.0); } nvar=(order)*(order+1)/2; tarr=(double *)malloc(sizeof(double)*nvar*2); dxfit=tarr,dyfit=tarr+nvar; diff_2d_poly(xfit,order,dxfit,dyfit); ma=eval_2d_poly(dx,dy,order-1,dxfit,0,0,1); mb=eval_2d_poly(dx,dy,order-1,dyfit,0,0,1); diff_2d_poly(yfit,order,dxfit,dyfit); mc=eval_2d_poly(dx,dy,order-1,dxfit,0,0,1); md=eval_2d_poly(dx,dy,order-1,dyfit,0,0,1); free(tarr); } else { ma=xfit[1],mb=xfit[2]; mc=yfit[1],md=yfit[2]; } n1=(ma-md)*(ma-md)+(mb+mc)*(mb+mc); n2=(ma+md)*(ma+md)+(mb-mc)*(mb-mc); nn=(n1=0 ; o-- ) { for ( i=0 ; i<=o ; i++ ) { coeff[n+o+1+i]+=lin[1]*coeff[n+i]; coeff[n+o+2+i]+=lin[2]*coeff[n+i]; coeff[n+i]*=lin[0]; } n-=o; } return(0); } int compose_2d_poly_with_affine(double *coeff,int order,double *xlin,double *ylin,double *rc) { double *xm,*ym,c,m,f; int nvar,i,o,j,n; if ( order<0 || coeff==NULL || xlin==NULL || ylin==NULL || rc==NULL ) return(-1); else if ( order==0 ) { rc[0]=coeff[0]; return(0); } nvar=(order+1)*(order+2)/2; xm=(double *)malloc(sizeof(double)*nvar); ym=(double *)malloc(sizeof(double)*nvar); xm[0]=ym[0]=1.0,rc[0]=0.0; for ( i=1 ; i #include #include #include #include #include "spline.h" /*****************************************************************************/ int spline_coeff(double *x,double *y,int n,double *yp1,double *ypn,double *y2) { int i,k; double p,qn,sig,un,*u; u=(double *)malloc(sizeof(double)*n); if ( yp1==NULL ) { y2[0]=u[0]=0.0; } else { y2[0]=-0.5; u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-(*yp1)); } for ( i=1 ; i=0 ; k-- ) { y2[k]=y2[k]*y2[k+1]+u[k]; } free(u); return(0); } double spline_inter(double *xa,double *ya,double *y2a,int n,double x) { int klo,khi,k; double a,b,h,y; klo=0,khi=n-1; while ( khi-klo>1 ) { k=(khi+klo)/2; if ( xa[k] > x ) khi=k; else klo=k; } h=xa[khi]-xa[klo]; a=(xa[khi]-x)/h,b=(x-xa[klo])/h; y=a*ya[klo]+b*ya[khi]+((a*a*a-a)*y2a[klo]+(b*b*b-b)*y2a[khi])*(h*h)/6.0; return(y); } double spline_inter_der(double *xa,double *ya,double *y2a,int n,double x) { int klo,khi,k; double a,b,h,y; klo=0,khi=n-1; while ( khi-klo>1 ) { k=(khi+klo)/2; if ( xa[k] > x ) khi=k; else klo=k; } h=xa[khi]-xa[klo]; a=(xa[khi]-x)/h,b=(x-xa[klo])/h; y=(-ya[klo]+ya[khi])/h+(-(3*a*a-1.0)*y2a[klo]+(3*b*b-1.0)*y2a[khi])*(h)/6.0; return(y); } /*****************************************************************************/ int natspline_coeff(double *y,int n,double *y2) { int i,k; double p,qn,un,*u; u=(double *)malloc(sizeof(double)*n); y2[0]=u[0]=0.0; for ( i=1 ; i=0 ; k-- ) { y2[k]=y2[k]*y2[k+1]+u[k]; } free(u); return(0); } double natspline_inter(double *ya,double *y2a,int n,double x) { int klo,khi; double a,b,y,d; klo=(int)x; khi=klo+1;d=x-(double)klo; a=(1.0-d),b=(d); y=a*ya[klo]+b*ya[khi]+((a*a*a-a)*y2a[klo]+(b*b*b-b)*y2a[khi])/6.0; return(y); } double natspline_inter_der(double *ya,double *y2a,int n,double x) { int klo,khi; double a,b,y,d; klo=(int)x; khi=klo+1;d=x-(double)klo; a=(1.0-d),b=(d); y=(-ya[klo]+ya[khi])+(-(3*a*a-1.0)*y2a[klo]+(3*b*b-1.0)*y2a[khi])/6.0; return(y); } /*****************************************************************************/ int cyspline_coeff(double *y,int n,double *y2) { if ( n <= 0 ) return(-1); else if ( n==1 ) { y2[0]=0.0; return(0); } else if ( n==2 ) { /* y2[0]=(4.0*(2*y[1]-2*y[0])-1.0*(2*y[0]-2*y[1]))/15.0; y2[1]=(4.0*(2*y[0]-2*y[1])-1.0*(2*y[1]-2*y[0]))/15.0; */ y2[0]=9*(2*y[1]-2*y[0])/3.0; y2[1]=9*(2*y[0]-2*y[1])/3.0; return(0); } else if ( n==3 ) { /* y2[0]=(5.0*(y[1]-2*y[0]+y[2])-1.0*(y[2]-2*y[1]+y[0])-1.0*(y[0]-2*y[2]+y[1]))/18.0; */ y2[0]=6*(-2*y[0]+y[1]+y[2])/3.0; y2[1]=6*(-2*y[1]+y[2]+y[0])/3.0; y2[2]=6*(-2*y[2]+y[0]+y[1])/3.0; return(0); } else { int *da,*db,i,j,s; da=(int *)malloc(sizeof(int)*(n+1)); db=(int *)malloc(sizeof(int)*(n+1)); da[0]=da[1]=db[0]=db[1]=0; da[2]=0,da[3]=1; db[2]=1,db[3]=0; for ( i=4 ; i<=n ; i++ ) { if ( i%2 ) { da[i]=2*da[i-1]+da[i-2]; db[i]=2*db[i-1]+db[i-2]; } else { da[i]=da[i-1]+da[i-2]; db[i]=db[i-1]+db[i-2]; } } for ( i=0 ; i=0 ; j-- ) { l[j] -= gam[j+1]*l[j+1]; } free(gam); return(0); } double intspline_inter(double *y,double *l,int n,double x,double len) { double tlen,ret,px,lx,ex; int p; tlen=(double)(n+1); if ( x<0.0 || x+len>tlen ) return(0.0); ret=0.0;p=(int)x;px=x-(double)p; while ( len>0.0 ) { lx=len; ex=px+lx; if ( ex>1.0 ) lx=1.0-px,ex=1.0; if ( lx==1.0 ) ret+=y[p]; else ret+=lx*(l[p]+ (ex+px)*(-2*l[p]-l[p+1]+3*y[p])+ (ex*(ex+px)+px*px)*(l[p]+l[p+1]-2*y[p])); p++; x=(double)p;px=0.0; len-=lx; }; return(ret); } /*****************************************************************************/ fitsh-0.9.2/src/math/spline/bicubic.c0000644000175000017500000000634411465370725016052 0ustar apalapal/*****************************************************************************/ /* bicubic.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for 2D cubic spline interpolation. */ /* (c) 2004, Pal, A. (apal@szofi.elte.hu) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in bicubic.h */ /*****************************************************************************/ #include #include #include #include #include "bicubic.h" /*****************************************************************************/ static int cubic_spline_coeff(double **y,int px,int py,int dx,int dy,int n,double **y2,int lx,int ly,double *u) { int i,k; double p,qn,un,yprev,ycurr,ynext; if ( n<=0 ) return(-1); else if ( n<2 ) { y2[ly][lx]=0.0; return(0); } y2[ly][lx]=u[0]=0.0; yprev=y[py][px]; py+=dy,px+=dx; ycurr=y[py][px]; for ( i=1 ; i=0 ; k-- ) { ycurr=y2[ly][lx]=y2[ly][lx]*ynext+u[k]; ly-=dy,lx-=dx; ynext=ycurr; } return(0); } int bicubic_coeff(double **y,int sx,int sy,double **c,char **mask) { int i,j,ms; double *tmp; ms=(sx>sy?sx:sy); tmp=(double *)malloc(sizeof(double)*ms); for ( i=0 ; ij0 ) { cubic_spline_coeff(c,2*j0,2*i,2,0,j-j0,c,2*j0+1,2*i,tmp); } } } for ( j=0 ; ji0 ) { cubic_spline_coeff(c,2*j+0,2*i0,0,2,i-i0,c,2*j+0,2*i0+1,tmp); cubic_spline_coeff(c,2*j+1,2*i0,0,2,i-i0,c,2*j+1,2*i0+1,tmp); } } } } free(tmp); return(0); } double bicubic_inter(double **c,double x,double y) { int ix,iy; double ax,bx,ay,by,ax3,bx3; double zb,zt,z2b,z2t,z; ix=(int)x,x-=(double)ix;ix=ix*2; iy=(int)y,y-=(double)iy;iy=iy*2; ay=(1.0-y),by=y; ax=(1.0-x),bx=x; ax3=(ax*ax*ax-ax)/6.0, bx3=(bx*bx*bx-bx)/6.0; zb =ax*c[iy ][ix]+bx*c[iy ][ix+2]+ax3*c[iy ][ix+1]+bx3*c[iy ][ix+3]; z2b=ax*c[iy+1][ix]+bx*c[iy+1][ix+2]+ax3*c[iy+1][ix+1]+bx3*c[iy+1][ix+3]; zt =ax*c[iy+2][ix]+bx*c[iy+2][ix+2]+ax3*c[iy+2][ix+1]+bx3*c[iy+2][ix+3]; z2t=ax*c[iy+3][ix]+bx*c[iy+3][ix+2]+ax3*c[iy+3][ix+1]+bx3*c[iy+3][ix+3]; z=ay*zb+by*zt+((ay*ay*ay-ay)*z2b+(by*by*by-by)*z2t)/6.0; return(z); } /*****************************************************************************/ fitsh-0.9.2/src/math/spline/biquad-isc.c0000644000175000017500000004766012771507725016504 0ustar apalapal/*****************************************************************************/ /* biquad-isc.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for integrating biquadratic surfaces on intersections: */ /* on circles, triangles, polygons and rectangles. Primary developed for */ /* weighted aperture photometry. This library is standalone, however, some */ /* related functions (to create and evaluate biquadratic interpolation */ /* surfaces) can be found in biquad.c. */ /* (c) 2004-05, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in biquad-isc.h */ /*****************************************************************************/ #include #include #include #include #include "biquad-isc.h" /*****************************************************************************/ /* Nontrivial coefficients of the biquadratic polynomial; derived from the */ /* appropriate subset of the array 'c' holding the surface coefficients */ /* (which are calculated by biquad_coeff(), for example). */ static int biquad_poly_coefficients(double **cf,double *pcf) { double wa1,wa2,wb1,wb2; pcf[0]=cf[0][0]; /* 1 */ pcf[1]=-4.0*cf[0][0]+6.0*cf[0][1]-2.0*cf[0][2]; /* x */ wa1 =-4.0*cf[1][0]+6.0*cf[1][1]-2.0*cf[1][2]; wa2 =-4.0*cf[2][0]+6.0*cf[2][1]-2.0*cf[2][2]; pcf[2]=3.0*(cf[0][0]-2.0*cf[0][1]+cf[0][2]); /* x^2 */ wb1 =3.0*(cf[1][0]-2.0*cf[1][1]+cf[1][2]); wb2 =3.0*(cf[2][0]-2.0*cf[2][1]+cf[2][2]); pcf[3]=-4.0*cf[0][0]+6.0*cf[1][0]-2.0*cf[2][0]; /* y */ pcf[4]=-4.0*pcf[1]+6.0*wa1-2.0*wa2; /* xy */ pcf[5]=-4.0*pcf[2]+6.0*wb1-2.0*wb2; /* x^2y */ pcf[6]=3.0*(cf[0][0]-2.0*cf[1][0]+cf[2][0]); /* y^2 */ pcf[7]=3.0*(pcf[1]-2.0*wa1+wa2); /* xy^2 */ pcf[8]=3.0*(pcf[2]-2.0*wb1+wb2); /* x^2y^2 */ return(0); } static double biquad_isc_integral_indefinite(double *pc,double r,double x) { double t,w,s,c, r2,r3,r4,r5,r6, c2,s2,c4,s4,sc,s2c2; s=x/r; if ( s<-1.0 ) s=-1.0; if ( s>+1.0 ) s=+1.0; t=asin(s);c=cos(t); c2=c*c,s2=s*s,c4=c2*c2,s4=s2*s2,sc=s*c,s2c2=s2*c2; r2=r*r,r3=r2*r,r4=r2*r2,r5=r2*r3,r6=r3*r3; w=+pc[0]*r2*0.5*(t+sc) /* 1 */ -pc[1]*r3*(c2*c)/3.0 /* x */ +pc[2]*r4*0.125*(t+sc*(s2-c2)) /* x^2 */ +pc[3]*r3*s*(0.5-s2/6.0) /* y */ -pc[4]*r4*c4/8.0 /* xy */ +pc[5]*r5*s*(s4+2.5*s2c2)/15.0 /* x^2y */ +pc[6]*r4*(3*t+sc*(2.0*c2+3.0))/24.0 /* y^2 */ -pc[7]*r5*c4*c/15.0 /* xy^2 */ +pc[8]*r6*((t+sc*(s4-c4))/48.0+s2c2*sc/18.0); /* x^2y^2 */ return(w); } static double biquad_isc_integral_semirect_definite(double *pc,double x1,double x2,double y2) { double w,sx,sx2,sy,sy2; sx=x2+x1,sx2=x2*sx+x1*x1;sx=sx/2.0,sx2=sx2/3.0; sy=y2 ,sy2=y2*sy ;sy=sy/2.0,sy2=sy2/3.0; w=(x2-x1)*y2* ( (pc[0]+pc[1]*sx+pc[2]*sx2) + sy *(pc[3]+pc[4]*sx+pc[5]*sx2) + sy2*(pc[6]+pc[7]*sx+pc[8]*sx2) ); return(w); } static double biquad_isc_integral_rect_definite(double *pc,double x1,double x2,double y1,double y2) { double w,sx,sx2,sy,sy2; sx=x2+x1,sx2=x2*sx+x1*x1;sx=sx/2.0,sx2=sx2/3.0; sy=y2+y1,sy2=y2*sy+y1*y1;sy=sy/2.0,sy2=sy2/3.0; w=(x2-x1)*(y2-y1)*( (pc[0]+pc[1]*sx+pc[2]*sx2) + sy *(pc[3]+pc[4]*sx+pc[5]*sx2) + sy2*(pc[6]+pc[7]*sx+pc[8]*sx2) ); return(w); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static double biquad_isc_int_pixel_semicircle(double *pc,double x1,double x2, double y1,double y2,double r) { double by,sy,dx1,dx2,s,w,a; by=y1; sy=y2-y1; if ( r<=by || by+sy<=0 ) return(0.0); if ( by<0.0 ) sy+=by,by=0.0; if ( sy<=0.0 ) return(0.0); if ( by+sy>=r ) { if ( by==0.0 ) dx1=-r,dx2=+r,s=0.0; else s=by,w=sqrt(r*r-s*s),dx1=-w,dx2=+w; if ( x2<=dx1 || x1>=dx2 ) return(0.0); if ( x1dx2 ) x2=dx2; a=biquad_isc_integral_indefinite(pc,r,x2)- biquad_isc_integral_indefinite(pc,r,x1)- biquad_isc_integral_semirect_definite(pc,x1,x2,by); return(a); } else { double hs,hx1,hx2,hdx1,hdx2,a1,a2; if ( by==0.0 ) dx1=-r,dx2=+r,s=0.0; else s=by,w=sqrt(r*r-s*s),dx1=-w,dx2=+w; if ( x2<=dx1 || x1>=dx2 ) return(0.0); if ( x1dx2 ) x2=dx2; hs=by+sy;w=sqrt(r*r-hs*hs);hdx1=-w,hdx2=+w; hx1=x1,hx2=x2; if ( hx1hdx2 ) hx2=hdx2; if ( hx1= cr*(cr+1.42)+0.5 ) return(0.0); /* The pixel is contained by the circle: */ if ( cdis2 <= cr*(cr-1.42)+0.5 && cr>=0.71 ) return(c[2*iy+1][2*ix+1]); /* The subset of the coefficients 'c' required by the integration...: */ cf[0]=&c[2*iy+0][2*ix]; cf[1]=&c[2*iy+1][2*ix]; cf[2]=&c[2*iy+2][2*ix]; biquad_poly_coefficients(cf,pcf); /* Shift the pixel and the circle to the bottom-left corner: */ cx-=(double)ix, cy-=(double)iy; /* Shift the polynomial coefficients to set the center of the circle to 0: */ acf[0]=pcf[0]+cx*(pcf[1]+cx*pcf[2])+ cy*((pcf[3]+cx*(pcf[4]+cx*pcf[5]))+ cy*(pcf[6]+cx*(pcf[7]+cx*pcf[8]))); acf[1]=pcf[1]+2*cx*pcf[2]+cy*((pcf[4]+2*cx*pcf[5])+cy*(pcf[7]+2*cx*pcf[8])); acf[2]=pcf[2]+cy*(pcf[5]+cy*pcf[8]); acf[3]=pcf[3]+cx*(pcf[4]+cx*pcf[5])+2*cy*(pcf[6]+cx*(pcf[7]+cx*pcf[8])); acf[4]=pcf[4]+2*cx*pcf[5]+2*cy*(pcf[7]+2*cx*pcf[8]); acf[5]=pcf[5]+2*cy*pcf[8]; acf[6]=pcf[6]+cx*(pcf[7]+cx*pcf[8]); acf[7]=pcf[7]+2*cx*pcf[8]; acf[8]=pcf[8]; /* Calculate the integral for the upper semicircle: */ iupper=biquad_isc_int_pixel_semicircle(acf,-cx,1.0-cx,-cy,1.0-cy,cr); /* Negate the coefficients of the polynomial which has odd order in 'y': */ acf[3]=-acf[3], acf[4]=-acf[4], acf[5]=-acf[5]; /* Calculate the integral for the lower semicircle: */ ilower=biquad_isc_int_pixel_semicircle(acf,-cx,1.0-cx, cy-1.0,cy,cr); return(iupper+ilower); } /*****************************************************************************/ double biquad_isc_int_subpixel(double **c,int ix,int iy,double x0,double y0,double x1,double y1) { double *cf[3],pcf[9],w; if ( x0>x1 ) w=x0,x0=x1,x1=w; if ( y0>y1 ) w=y0,y0=y1,y1=w; if ( x0<0.0 ) x0=0.0; if ( y0<0.0 ) y0=0.0; if ( x0>1.0 ) x0=1.0; if ( y0>1.0 ) y0=1.0; cf[0]=&c[2*iy+0][2*ix]; cf[1]=&c[2*iy+1][2*ix]; cf[2]=&c[2*iy+2][2*ix]; biquad_poly_coefficients(cf,pcf); w=biquad_isc_integral_rect_definite(pcf,x0,x1,y0,y1); return(w); } static double biquad_isc_int_subpixel_nt(double **c,int ix,int iy,double x0,double y0,double x1,double y1) { double *cf[3],pcf[9],w; cf[0]=&c[2*iy+0][2*ix]; cf[1]=&c[2*iy+1][2*ix]; cf[2]=&c[2*iy+2][2*ix]; biquad_poly_coefficients(cf,pcf); w=biquad_isc_integral_rect_definite(pcf,x0,x1,y0,y1); return(w); } double biquad_isc_int_rectangle(double **c,double x0,double y0,double x1,double y1) { double w,ret; int sig,ix0,ix1,iy0,iy1,x,y; sig=1; if ( x0>x1 ) sig=-sig,w=x0,x0=x1,x1=w; if ( y0>y1 ) sig=-sig,w=y0,y0=y1,y1=w; ix0=(int)x0,iy0=(int)y0; ix1=(int)x1,iy1=(int)y1; x0-=(double)ix0,y0-=(double)iy0; x1-=(double)ix1,y1-=(double)iy1; if ( ix0==ix1 ) { if ( iy0==iy1 ) ret=biquad_isc_int_subpixel_nt(c,ix0,iy0,x0,y0,x1,y1); else { ret=biquad_isc_int_subpixel_nt(c,ix0,iy0,x0,y0,x1,1.0); for ( y=iy0+1 ; y0.0 ) ret+=biquad_isc_int_subpixel_nt(c,ix0,iy1,x0,0.0,x1,y1); } } else { if ( iy0==iy1 ) { ret=biquad_isc_int_subpixel_nt(c,ix0,iy0,x0,y0,1.0,y1); for ( x=ix0+1 ; x0.0 ) ret+=biquad_isc_int_subpixel_nt(c,ix1,iy0,0.0,y0,x1,y1); } else { ret=biquad_isc_int_subpixel_nt(c,ix0,iy0,x0,y0,1.0,1.0); for ( x=ix0+1 ; x0.0 ) ret+=biquad_isc_int_subpixel_nt(c,ix1,iy0,0.0,y0,x1,1.0); for ( y=iy0+1 ; y0.0 ) ret+=biquad_isc_int_subpixel_nt(c,ix1,y,0.0,0.0,x1,1.0); } if ( y1>0.0 ) { ret+=biquad_isc_int_subpixel_nt(c,ix0,iy1,x0,0.0,1.0,y1); for ( x=ix0+1 ; x0.0 ) ret+=biquad_isc_int_subpixel_nt(c,ix1,iy1,0.0,0.0,x1,y1); } } } if ( sig>0 ) return(ret); else return(-ret); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int biquad_isc_int_block_subpixels(double **c,int ix,int iy,int nx,int ny,double **ret) { double *cf[3],pcf[9],w,x0,y0,x1,y1; int i,j; if ( nx<=0 || ny<=0 ) return(1); cf[0]=&c[2*iy+0][2*ix]; cf[1]=&c[2*iy+1][2*ix]; cf[2]=&c[2*iy+2][2*ix]; biquad_poly_coefficients(cf,pcf); y1=0.0; for ( i=0 ; iside<((vertex *)c2)->side ) return(-1); else if ( ((vertex *)c1)->side>((vertex *)c2)->side ) return(1); else if ( ((vertex *)c1)->delta<((vertex *)c2)->delta ) return(-1); else if ( ((vertex *)c1)->delta>((vertex *)c2)->delta ) return(1); else return(0); } static double biquad_isc_int_subpolygon(double *pcf,double *xcf,double *ps,int np) { double x,y,x1,y1,x2,y2; double dx1,dy1,dx2,dy2,jac; int i; double acf[15],bcf[15],ccf[15],ret,tret,w; x=ps[0],y=ps[1],x1=ps[2],y1=ps[3];ps+=4;dx1=x1-x,dy1=y1-y; np-=2; tret=0.0; for ( ; np>0 ; x1=x2,dx1=dx2,y1=y2,dy1=dy2,ps+=2,np-- ) { x2=ps[0],y2=ps[1]; dx2=x2-x,dy2=y2-y; jac=dx1*dy2-dx2*dy1; if ( jac==0.0 ) continue; ret=xcf[0]*pcf[0]; acf[0]=x, acf[1]=dx1, acf[2]=dx2; for ( w=0.0,i=0 ; i<3 ; i++ ) w+=acf[i]*xcf[i]; ret+=pcf[1]*w; bcf[0]=x*x, bcf[1]=2*x*dx1, bcf[2]=2*x*dx2, bcf[3]=dx1*dx1, bcf[4]=2*dx1*dx2, bcf[5]=dx2*dx2; for ( w=0.0,i=0 ; i<6 ; i++ ) w+=bcf[i]*xcf[i]; ret+=pcf[2]*w; acf[0]=y; acf[1]=dy1; acf[2]=dy2; for ( w=0.0,i=0 ; i<3 ; i++ ) w+=acf[i]*xcf[i]; ret+=pcf[3]*w; bcf[0]=x*acf[0], bcf[1]=x*acf[1]+dx1*acf[0], bcf[2]=x*acf[2]+dx2*acf[0], bcf[3]=dx1*acf[1], bcf[4]=dx1*acf[2]+dx2*acf[1], bcf[5]=dx2*acf[2]; for ( w=0.0,i=0 ; i<6 ; i++ ) w+=bcf[i]*xcf[i]; ret+=pcf[4]*w; ccf[0]=x*bcf[0], ccf[1]=x*bcf[1]+dx1*bcf[0], ccf[2]=x*bcf[2]+dx2*bcf[0], ccf[3]=x*bcf[3]+dx1*bcf[1], ccf[4]=x*bcf[4]+dx1*bcf[2]+dx2*bcf[1], ccf[5]=x*bcf[5]+dx2*bcf[2], ccf[6]=dx1*bcf[3], ccf[7]=dx1*bcf[4]+dx2*bcf[3], ccf[8]=dx1*bcf[5]+dx2*bcf[4], ccf[9]=dx2*bcf[5]; for ( w=0.0,i=0 ; i<10 ; i++ ) w+=ccf[i]*xcf[i]; ret+=pcf[5]*w; acf[0]=y*y, acf[1]=2*y*dy1, acf[2]=2*y*dy2, acf[3]=dy1*dy1, acf[4]=2*dy1*dy2, acf[5]=dy2*dy2; for ( w=0.0,i=0 ; i<6 ; i++ ) w+=acf[i]*xcf[i]; ret+=pcf[6]*w; bcf[0]=x*acf[0], bcf[1]=x*acf[1]+dx1*acf[0], bcf[2]=x*acf[2]+dx2*acf[0], bcf[3]=x*acf[3]+dx1*acf[1], bcf[4]=x*acf[4]+dx1*acf[2]+dx2*acf[1], bcf[5]=x*acf[5]+dx2*acf[2], bcf[6]=dx1*acf[3], bcf[7]=dx1*acf[4]+dx2*acf[3], bcf[8]=dx1*acf[5]+dx2*acf[4], bcf[9]=dx2*acf[5]; for ( w=0.0,i=0 ; i<10 ; i++ ) w+=bcf[i]*xcf[i]; ret+=pcf[7]*w; ccf[0]=x*bcf[0], ccf[1]=x*bcf[1]+dx1*bcf[0], ccf[2]=x*bcf[2]+dx2*bcf[0], ccf[3]=x*bcf[3]+dx1*bcf[1], ccf[4]=x*bcf[4]+dx1*bcf[2]+dx2*bcf[1], ccf[5]=x*bcf[5]+dx2*bcf[2], ccf[6]=x*bcf[6]+dx1*bcf[3], ccf[7]=x*bcf[7]+dx1*bcf[4]+dx2*bcf[3], ccf[8]=x*bcf[8]+dx1*bcf[5]+dx2*bcf[4], ccf[9]=x*bcf[9]+dx2*bcf[5], ccf[10]=dx1*bcf[6], ccf[11]=dx1*bcf[7]+dx2*bcf[6], ccf[12]=dx1*bcf[8]+dx2*bcf[7], ccf[13]=dx1*bcf[9]+dx2*bcf[8], ccf[14]=dx2*bcf[9]; for ( w=0.0,i=0 ; i<15 ; i++ ) w+=ccf[i]*xcf[i]; ret+=pcf[8]*w; tret+=ret*jac; } return(tret); } #define int_round(x,i) do { if ( fabs(x-i)<1e-8 ) x=i;else if ( fabs(x-1.0-i)<1e-8 ) x=i+1,i++; } while (0) double biquad_isc_int_triangle(double **c,int is_spline,double x1,double y1,double x2,double y2,double x3,double y3,int sx,int sy) { int ix1,iy1,ix2,iy2,ix3,iy3; int minx,maxx,miny,maxy,ix,iy,i,j,k,ii; int nv,cv,iv,np; vertex vert_stat[STATIC_VERTICES],*vert_dyn,*vert,*v,vl[8]; double ret,x,y,points[20],pcf[9],*cf[3],det,xcf[15],fa,fb; if ( c==NULL ) return(0.0); /* Re-arrange the point into counter-clockwise order */ det=(x2-x1)*(y3-y1)-(x3-x1)*(y2-y1); if ( det==0.0 ) return(0.0); else if ( det<0.0 ) x=x3,x3=x2,x2=x,y=y3,y3=y2,y2=y; ix1=(int)x1,ix2=(int)x2,ix3=(int)x3; iy1=(int)y1,iy2=(int)y2,iy3=(int)y3; /* int_round(x1,ix1); int_round(x2,ix2); int_round(x3,ix3); int_round(y1,iy1); int_round(y2,iy2); int_round(y3,iy3);*/ /* fprintf(stdout,"%.16f %.16f %.16f %.16f %.16f %.16f\n",x1,y1,x2,y2,x3,y3); */ nv=3+ abs(ix1-ix2)+abs(ix2-ix3)+abs(ix3-ix1)+ abs(iy1-iy2)+abs(iy2-iy3)+abs(iy3-iy1); if ( nv<=STATIC_VERTICES ) { vert_dyn=NULL, vert=vert_stat; } else { vert_dyn=(vertex *)malloc(sizeof(vertex)*nv), vert=vert_dyn; } cv=0; cv+=biquad_isc_it_build_side(vert+cv,x1,y1,x2,y2,ix1,iy1,ix2,iy2,0); cv+=biquad_isc_it_build_side(vert+cv,x2,y2,x3,y3,ix2,iy2,ix3,iy3,1); cv+=biquad_isc_it_build_side(vert+cv,x3,y3,x1,y1,ix3,iy3,ix1,iy1,2); if ( cv > nv ) /* inconsistency */ { return(0.0); } else nv=cv; for ( i=0 ; i=1.0 || ( vert[i].delta<=0.0 && vert[i].type>0 ) ) vert[i].type=-1; } qsort(vert,nv,sizeof(vertex),biquad_isc_it_compare); for ( i=0 ; i0 && vert[i].type>0 && vert[i-1].delta==vert[i].delta ) vert[i].type=-1; } /* fprintf(stderr,"biit(): db0: (%g,%g) (%g,%g) (%g,%g)\n",x1,y1,x2,y2,x3,y3); for ( i=0 ; imaxx ) maxx=ix2;if ( ix3>maxx ) maxx=ix3; miny=iy1;if ( iy2maxy ) maxy=iy2;if ( iy3>maxy ) maxy=iy3; xcf[0]=fa=0.5;k=1; for ( i=1 ; i<=4 ; i++ ) { fa=fa*(double)i/(double)(i+2); for ( j=0,fb=fa ; j<=i ; j++,k++ ) { xcf[k]=fb; if ( j=0 && ( iy<0 || iy>=sy ) ) continue; for ( ix=minx ; ix<=maxx ; ix++ ) { if ( sx>=0 && ( ix<0 || ix>=sx ) ) continue; for ( i=0,iv=0,v=vert ; itype==0 && ix<=v->x && v->x<=ix+1 && iy<=v->y && v->y<=iy+1 ) { vl[iv].type=0; x=vl[iv].x=v->x-ix, y=vl[iv].y=v->y-iy; if ( x<=0.0 ) vl[iv].type=1; else if ( x>=1.0 ) vl[iv].type=3; else if ( y<=0.0 ) vl[iv].type=2; else if ( y>=1.0 ) vl[iv].type=4; vl[iv].side=v->side; vl[iv].delta=0.0; iv++; } else if ( v->type==1 && iy<=v->y && v->y<=iy+1 ) { if ( v->x==ix ) { vl[iv].type=1, vl[iv].x=0.0, vl[iv].y=v->y-iy; vl[iv].side=v->side; vl[iv].delta=v->delta; iv++; } if ( v->x==ix+1 ) { vl[iv].type=3, vl[iv].x=1.0, vl[iv].y=v->y-iy; vl[iv].side=v->side; vl[iv].delta=v->delta; iv++; } } else if ( v->type==2 && ix<=v->x && v->x<=ix+1 ) { if ( v->y==iy ) { vl[iv].type=2, vl[iv].x=v->x-ix, vl[iv].y=0.0; vl[iv].side=v->side; vl[iv].delta=v->delta; iv++; } if ( v->y==iy+1 ) { vl[iv].type=4, vl[iv].x=v->x-ix, vl[iv].y=1.0; vl[iv].side=v->side; vl[iv].delta=v->delta; iv++; } } } if ( iv<=1 ) { x=(double)ix+0.5, y=(double)iy+0.5; /* is (x,y) inside the triangle or not...?! */ ii=biquad_isc_is_inside(x1,y1,x2,y2,x3,y3,x,y); if ( ii ) { if ( is_spline ) ret+=c[2*iy+1][2*ix+1]; else ret+=c[iy][ix]; } /*fprintf(stderr,"[%d,%d] [%d]\n",ix,iy,ii);*/ /*DB1*/ } else { vertex *pv,*vv; double *pp; int k; pv=&vl[iv-1]; pp=&points[0]; pp[0]=pv->x,pp[1]=pv->y; np=1;pp+=2; for ( i=0,vv=vl ; idelta<=0.0 && ((pv->side+1)%3==(vv->side)%3) ) { pp[0]=vv->x,pp[1]=vv->y; pp+=2;np++; } else if ( vv->delta<=0.0 && ((pv->side+1)%3==(vv->side)%3) ) { pp[0]=vv->x,pp[1]=vv->y; pp+=2;np++; } else if ( pv->side==vv->side && pv->deltadelta ) { pp[0]=vv->x,pp[1]=vv->y; pp+=2;np++; } else { k=pv->type; while ( k%4 != (vv->type)%4 ) { if ( k%4==1 ) pp[0]=0.0,pp[1]=0.0; if ( k%4==2 ) pp[0]=1.0,pp[1]=0.0; if ( k%4==3 ) pp[0]=1.0,pp[1]=1.0; if ( k%4==0 ) pp[0]=0.0,pp[1]=1.0; pp+=2;np++,k++; }; pp[0]=vv->x,pp[1]=vv->y; pp+=2;np++; } } if ( points[2*np-2]==points[0] && points[2*np-1]==points[1] ) np--; /*fprintf(stdout,"[np=%d]\n",np); fprintf(stdout,"[%d,%d]",ix,iy); for ( k=0 ; k #include #include #include #include "biquad.h" /*****************************************************************************/ static int intspline_coeff_2d(double **y,int px,int py,int dx,int dy,int n,double **l,int lx,int ly,double *tmp) { double bet,yprev,ycurr=0.0,lfoll; int j; if ( n<=0 ) return(1); else if ( n==1 ) { l[ly][lx]=l[ly+dy][lx+dx]=y[py][px]; return(0); } yprev=y[py][px]; l[ly][lx]=2.0*yprev; bet=1.0; for ( j=1 ; j=0 ; j-- ) { l[ly][lx] -= tmp[j+1]*lfoll; lfoll=l[ly][lx]; lx-=dx, ly-=dy; } return(0); } int biquad_smooth(double **c,int sx,int sy,char **mask) { int i,j,tmpsize; double *tmp; tmpsize=sx; if ( tmpsize < sy ) tmpsize=sy; tmpsize++; tmp=(double *)malloc(sizeof(double)*tmpsize); if ( mask==NULL ) { for ( i=1 ; i<2*sx+1 ; i+=2 ) { intspline_coeff_2d(c,i,1,0,2,sy,c,i,0,tmp); } for ( i=0 ; i<2*sy+1 ; i++ ) { intspline_coeff_2d(c,1,i,2,0,sx,c,0,i,tmp); } } else { int i0,j0; for ( i=0 ; ij0 ) { intspline_coeff_2d(c,2*j0+1,2*i+1,2,0,j-j0,c,2*j0,2*i+1,tmp); } } } for ( j=0 ; ji0 ) { intspline_coeff_2d(c,2*j+1,2*i0+1,0,2,i-i0,c,2*j+1,2*i0,tmp); } } } for ( j=0 ; jj0 ) { intspline_coeff_2d(c,2*j0+1,0,2,0,j-j0,c,2*j0,0,tmp); } } for ( i=1 ; ij0 ) { intspline_coeff_2d(c,2*j0+1,2*i,2,0,j-j0,c,2*j0,2*i,tmp); } } } for ( j=0 ; jj0 ) { intspline_coeff_2d(c,2*j0+1,2*sy,2,0,j-j0,c,2*j0,2*sy,tmp); } } } free(tmp); return(0); } int biquad_coeff(double **y,int sx,int sy,double **c,char **mask) { int i,j; for ( i=0 ; i0.0 ) ret=-1; else if ( tr<0.0 ) ret=+1; else return(0); mx=-(+coeff[5]*coeff[1]-coeff[4]*coeff[2])/det; my=-(-coeff[4]*coeff[1]+coeff[3]*coeff[2])/det; if ( mx<0 || my<0 || mx>1.0 || my>1.0 ) return(0); if ( mmr != NULL ) *mmr=coeff[0]-(coeff[1]*coeff[1]*coeff[5]-2*coeff[1]*coeff[2]*coeff[4]+coeff[2]*coeff[2]*coeff[3])/(2.0*det); if ( rx != NULL ) *rx=mx; if ( ry != NULL ) *ry=my; return(ret); } /*****************************************************************************/ static int biquad_poly_coefficients(double **cf,double *pcf) { double wa1,wa2,wb1,wb2; pcf[0]=cf[0][0]; pcf[1]=-4.0*cf[0][0]+6.0*cf[0][1]-2.0*cf[0][2]; wa1 =-4.0*cf[1][0]+6.0*cf[1][1]-2.0*cf[1][2]; wa2 =-4.0*cf[2][0]+6.0*cf[2][1]-2.0*cf[2][2]; pcf[2]=3.0*(cf[0][0]-2.0*cf[0][1]+cf[0][2]); wb1 =3.0*(cf[1][0]-2.0*cf[1][1]+cf[1][2]); wb2 =3.0*(cf[2][0]-2.0*cf[2][1]+cf[2][2]); pcf[3]=-4.0*cf[0][0]+6.0*cf[1][0]-2.0*cf[2][0]; pcf[4]=-4.0*pcf[1]+6.0*wa1-2.0*wa2; pcf[5]=-4.0*pcf[2]+6.0*wb1-2.0*wb2; pcf[6]=3.0*(cf[0][0]-2.0*cf[1][0]+cf[2][0]); pcf[7]=3.0*(pcf[1]-2.0*wa1+wa2); pcf[8]=3.0*(pcf[2]-2.0*wb1+wb2); return(0); } double biquad_int_pixel(double **c,int x,int y) { double r; r=c[2*y+1][2*x+1]; return(r); } double biquad_int_square_pixel(double **c,int x,int y) { double *cf[3],p[9],s2; x=2*x,y=2*y; cf[0]=&c[y+0][x]; cf[1]=&c[y+1][x]; cf[2]=&c[y+2][x]; biquad_poly_coefficients(cf,p); s2= (p[0]*p[0])+ (p[0]*(p[1]+p[3]))+ (p[1]*p[1]+p[3]*p[3]+2.0*p[0]*(p[2]+p[6]))/3.0+ (p[1]*p[3]+p[0]*p[4]+p[1]*p[2]+p[3]*p[6])/2.0+ (p[0]*p[7]+p[3]*p[4]+p[1]*p[6]+p[0]*p[5]+p[1]*p[4]+p[3]*p[2])/3.0+ (p[2]*p[2]+p[6]*p[6])/5.0+ (p[3]*p[7]+p[4]*p[6]+p[5]*p[1]+p[4]*p[2])/4.0+ (p[4]*p[4]+2.0*(p[0]*p[8]+p[1]*p[7]+p[3]*p[5]+p[2]*p[6]))/9.0+ (p[8]*p[3]+p[7]*p[4]+p[5]*p[6]+p[8]*p[1]+p[5]*p[4]+p[7]*p[2])/6.0+ (p[2]*p[5]+p[6]*p[7])/5.0+ (p[7]*p[7]+p[5]*p[5]+2.0*(p[6]*p[8]+p[2]*p[8]))/15.0+ (p[5]*p[7]+p[4]*p[8])/8.0+ (p[8]*p[7]+p[8]*p[5])/10.0+ (p[8]*p[8])/25.0; return(s2); } double biquad_scatter(double **c,int x,int y) { double s1,s2,s; s1=biquad_int_pixel(c,x,y); s2=biquad_int_square_pixel(c,x,y); s=s2-s1*s1; if ( s<0.0 ) return(0.0); else return(sqrt(s)); } /*****************************************************************************/ int biquad_diff(double **c,int sx,int sy,double **d,char **mask,int var) { int i,j; double l,t,r; if ( mask==NULL ) { if ( ! var ) /* var is zero/false: differentiation by 'x' */ { for ( i=0 ; i<=2*sy ; i++ ) { l=c[i][0],t=c[i][1],r=c[i][2]; for ( j=0 ; j<2*sx ; j+=2 ) { l=c[i][j],t=c[i][j+1],r=c[i][j+2]; d[i][j+0]=-4*l+6*t-2*r; d[i][j+1]=-l+r; } d[i][j]=+2*l-6*t+4*r; } } else /* var is nonzero/true: differentiation by 'x' */ { for ( j=0 ; j<=2*sx ; j++ ) { l=c[0][j],t=c[1][j],r=c[2][j]; for ( i=0 ; i<2*sy ; i+=2 ) { l=c[i][j],t=c[i+1][j],r=c[i+2][j]; d[i+0][j]=-4*l+6*t-2*r; d[i+1][j]=-l+r; } d[i][j]=+2*l-6*t+4*r; } } } else /* **TBD** now it is the same code which is okay but slower */ { if ( ! var ) /* var is zero/false: differentiation by 'x' */ { for ( i=0 ; i<=2*sy ; i++ ) { l=c[i][0],t=c[i][1],r=c[i][2]; for ( j=0 ; j<2*sx ; j+=2 ) { l=c[i][j],t=c[i][j+1],r=c[i][j+2]; d[i][j+0]=-4*l+6*t-2*r; d[i][j+1]=-l+r; } d[i][j]=+2*l-6*t+4*r; } } else /* var is nonzero/true: differentiation by 'x' */ { for ( j=0 ; j<=2*sx ; j++ ) { l=c[0][j],t=c[1][j],r=c[2][j]; for ( i=0 ; i<2*sy ; i+=2 ) { l=c[i][j],t=c[i+1][j],r=c[i+2][j]; d[i+0][j]=-4*l+6*t-2*r; d[i+1][j]=-l+r; } d[i][j]=+2*l-6*t+4*r; } } } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/math/spline/spline.h0000644000175000017500000000552411214467371015744 0ustar apalapal/*****************************************************************************/ /* spline.h */ /*****************************************************************************/ #ifndef __SPLINE_H_INCLUDED #define __SPLINE_H_INCLUDED 1 /*****************************************************************************/ /* spline_coeff(): Calculates the cubic spline coefficients for the data points y[] defined in the domain x[]. Both of the sets should contain 'n' points. The spline coefficients are returned in 'y2' ('n' real numbers). The 'yp1' and 'ypn' pointers should point to two real numbers, to the second derivatives for the fitted spline in the first (x[0]) and last (x[n-1]) point. If any of these pointers are NULL, the natural spline approximation is used (so the second derivative in the first and the last point is 0. */ int spline_coeff(double *x,double *y,int n,double *yp1,double *ypn,double *y2); /* spline_inter(), spline_inter_der(): Interpolates the x[]-y[] function and its derivative in the point 'xp' using a cubic spline interpolation with the coefficiens 'y2' (calculated by spline_coeff()). */ double spline_inter(double *x,double *y,double *y2,int n,double xp); double spline_inter_der(double *x,double *y,double *y2,int n,double xp); /* natspline_coeff(): Calculated the natural cubic spline coefficiens of the data points y[] defined in the domain 0,...,n-1. The spline coefficients are returned in 'y2'. The coefficients calculated are equal to the coefficients returned by spline_coeff() if x[i]=i (i=0,...,n-1) and yp1=ypn=NULL. */ int natspline_coeff(double *y,int n,double *y2); /* natspline_inter(), natspline_inter_der(): Interpolates the y[i] function and its derivative in the point 'x' using a (natural) cubic spline interpolation with the coefficients 'y2'. */ double natspline_inter(double *ya,double *y2a,int n,double x); double natspline_inter_der(double *ya,double *y2a,int n,double x); /* cyspline_coeff(): Calculated the cyclic cubic spline coefficiens of the data points y[] defined in the domain 0,...,n-1. The spline coefficients are returned in the array 'y2'. */ int cyspline_coeff(double *y,int n,double *y2); /* cyspline_inter(), cyspline_inter_der(): Interpolates the y[i] function and its derivative in the point 'x' using a cyclic cubic spline interpolation with the coefficients 'y2'. */ double cyspline_inter(double *ya,double *y2a,int n,double x); double cyspline_inter_der(double *ya,double *y2a,int n,double x); int intspline_coeff(double *y,int p,double *l); double intspline_inter(double *y,double *l,int n,double x,double len); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/math/spline/biquad-isc.h0000644000175000017500000000665410667340116016476 0ustar apalapal/*****************************************************************************/ /* biquad-isc.h */ /*****************************************************************************/ #ifndef __BIQUAD_ISC_H_INCLUDED #define __BIQUAD_ISC_H_INCLUDED 1 /* biquad_isc_int_pixel_circle(): Calculates the integral of the biquadratic surface 'c' on the intersecion of the pixel (ix,iy) (thus, the rectangle ['ix':'ix'+1,'iy':'iy'+1]) and the circle with a center of ('cx','cy') and radius of 'cr'. If the circle and the rectangle are disjoint, the function returns 0, otherwise it returns the desired integral. To create such biquadratic interpolation surfaces, the function biquad_coeff() can be used (see also biquad.c or biquad.h). */ double biquad_isc_int_pixel_circle(double **c,int ix,int iy,double cx, double cy,double cr); /* biquad_isc_int_subpixel(): Calculates the integral of the biquadratic surface 'c' on the subrectangle ['x0':'x1','y0':'y1'] of the pixel ('iy','ix'). The quantities 'x0', 'y0', 'x1' and 'y1' should be between 0 and 1, otherwise the integral will be limited to the intersection of the rectangle ['x0':'x1','y0':'y1'] and the rectangle [0:1,0:1]. */ double biquad_isc_int_subpixel(double **c,int ix,int iy, double x0,double y0,double x1,double y1); /* biquad_isc_int_rectangle(): Calcluates the integral of the biquadratic surface 'c' on the rectangl ['x0':'x1','y0':'y1']. Note that 'x0' and 'x1' should be between 0 and sx and 'y0' and 'y1' shouldbe between 0 and sy, otherwise the integration might spectaculary fail (with segmentation fault). */ double biquad_isc_int_rectangle(double **c, double x0,double y0,double x1,double y1); /* biquad_isc_int_block_subpixels(): Calculates the integral of the biquadratic surface 'c' to all subpixels of the pixel ('iy','ix') on a grid with a size of 'nx' times 'ny'. The integrals are stored in the array 'ret' where must be enough space allocated for them. The function returns 0, if both 'nx' and 'ny' are positive. Otherwise the function returns a nonzero value. Note that because of the sigma-subadditiviy of the integral and the properties of the biquadratic surface storage method in arrays like 'c' (generated by biquad_coeff(), see also biquad.c), the sum of the integrals returned in 'ret' is always c[2*iy+1][2*ix+1]. */ int biquad_isc_int_block_subpixels(double **c,int ix,int iy, int nx,int ny,double **ret); /* biquad_isc_int_triangle(): This function integrates the biquadratic surface described by the coefficients 'c' on the area of the triangle (x1,y1)-(x2,y2)-(x3,y3). The coordinates (xn and yn) should be in the intervals [0,sx] and [0,sy], respectively where sx and sy are the horizontal and vertical dimensions of the surface (see also biquad_coeff()). In other cases the parts of the integral outside the domain [0,sx]x[0,sy] are going to be zero (if both sx and sy are positive) or the function might spectaculary fail (with segmentation fault, if any of sx or sy is non- positive). The sign of the integral does not depend on the ordering of the points (it can be both counter-clockwise and clockwise, the result is going to be the same). */ double biquad_isc_int_triangle(double **c,int is_spline, double x1,double y1,double x2,double y2,double x3,double y3, int sx,int sy); #endif fitsh-0.9.2/src/math/Makefile.in0000644000175000017500000000304112766260037015047 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ CFLAGS=@CFLAGS@ all: dirs $(MAKE) targets dirs: dft fit intersec spline elliptic expint targets: poly.o polyfit.o match.a splinefit.o polygon.o .PHONY: all clean fit elliptic intersec spline expint dft dirs targets ############################################################################### dft: $(MAKE) -C dft elliptic: $(MAKE) -C elliptic expint: $(MAKE) -C expint fit: $(MAKE) -C fit intersec: $(MAKE) -C intersec spline: $(MAKE) -C spline ############################################################################### tpoint.o: tpoint.c tpoint.h $(CC) $(CFLAGS) -c tpoint.c cpmatch.o: cpmatch.c cpmatch.h $(CC) $(CFLAGS) -c cpmatch.c spmatrix.o: spmatrix.c spmatrix.h $(CC) $(CFLAGS) -c spmatrix.c delaunay.o: delaunay.c delaunay.h $(CC) $(CFLAGS) -c delaunay.c poly.o: poly.c poly.h $(CC) $(CFLAGS) -c poly.c polyfit.o: polyfit.c polyfit.h $(CC) $(CFLAGS) -c polyfit.c polygon.o: polygon.c polygon.h $(CC) $(CFLAGS) -c polygon.c splinefit.o: splinefit.c splinefit.h $(CC) $(CFLAGS) -c splinefit.c trimatch.o: trimatch.c trimatch.h $(CC) $(CFLAGS) -c trimatch.c match.a: tpoint.o cpmatch.o spmatrix.o delaunay.o trimatch.o $(AR) src match.a tpoint.o cpmatch.o spmatrix.o delaunay.o trimatch.o $(RANLIB) match.a ############################################################################### clean: $(MAKE) -C dft clean $(MAKE) -C elliptic clean $(MAKE) -C expint clean $(MAKE) -C fit clean $(MAKE) -C intersec clean $(MAKE) -C spline clean rm -f *.o *.a fitsh-0.9.2/src/math/polygon.h0000644000175000017500000000175012531371302014633 0ustar apalapal/*****************************************************************************/ /* polygon.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2015; Pal, A. */ /*****************************************************************************/ #ifndef __POLYGON_H_INCLUDED #define __POLYGON_H_INCLUDED 1 /*****************************************************************************/ double polygon_area(double *poly,int n); double polygon_area_signed(double *poly,int n); int polygon_convexity(double *poly,int n); int polygon_intersection_halfplane(double *poly,int n,double px,double py,double nx,double ny); int polygon_intersection_square(double *poly,int n,double x0,double y0,double dx,double dy); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/math/dft/0000755000175000017500000000000012772016355013560 5ustar apalapalfitsh-0.9.2/src/math/dft/pbfft.c0000644000175000017500000001015011173703553015017 0ustar apalapal/*****************************************************************************/ /* pbfft.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for Fast Fourier Transformation, based on the */ /* prime-based FFT (PBFFT) algorithm. */ /* (c) 2001-2003, 2004, Pal A. (apal@szofi.elte.hu) */ /* Last modified: 2006.10.23 */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in pbfft.h. */ /*****************************************************************************/ #include #include #include #include "pbfft.h" #ifndef M_PI #define M_PI 3.1415926535897932384626433832795028841968 #endif typedef struct { int prime[32]; complex *exp,*work; int size,type; } pbfftcache; static pbfftcache cache={ {1}, NULL,NULL, 0, 0 }; /* TBD: should be obsoleted by the upcoming implementation, see the commented code of pbfft_getprimdivs() just right after this function. */ static void pbfft_getprimdivs(int n,int *r) { int k; while ( n>1 ) { if ( n%2==0 ) *r=2,r++,n/=2; else break; } for ( k=3 ; n>1 ; ) { if ( n%k==0 ) *r=k,r++,n=n/k; else k+=2; } *r=0; } /* static void pbfft_getprimdivs(int n,int *r) { int k,w; while ( n>1 ) { if ( n%2==0 ) *r=2,r++,n/=2; else break; } for ( k=3,w=9 ; n>1 && w<=n ; ) { if ( n%k==0 ) *r=k,r++,n=n/k; else w+=4*k+4,k+=2; } if ( n>1 ) *r=n,r++; *r=0; } */ static int pbfft_get_reversal(int n,int *pbb) { int i,j,wd[32]; i=0; while ( *pbb ) { wd[i]=n%(*pbb), n=n/(*pbb); i++,pbb++; }; j=1,n=0; while ( i ) { i--,pbb--; n+=j*wd[i],j=j*(*pbb); }; return(n); } static void pbfft_setpwr(complex *x,double a) { x->re=cos(a); x->im=sin(a); } static void pbfft_set_expbuffer(complex *eb,int n,int typ) { int i; if ( typ ) typ=1; else typ=-1; for ( i=0 ; i */ /*****************************************************************************/ #include #include #include #include #include #include "polygon.h" /*****************************************************************************/ #define ix(i) (poly[2*((i)%(n))+0]) #define iy(i) (poly[2*((i)%(n))+1]) #define inhalf(i) ((ix(i)-px)*nx+(iy(i)-py)*ny) #define flag(i) flags[(i)%(n)] /*****************************************************************************/ double polygon_area_signed(double *poly,int n) { double mx,my,a; int i; if ( n <= 2 ) return(0.0); mx=my=0; for ( i=0 ; i= 0.0 ) np++; else nn++; } c=(np #include #include #include "tpoint.h" /*****************************************************************************/ /* create/set/destroy a point array */ tpointarr *tpoint_createarr(void) { tpointarr *arr=malloc(sizeof(*arr)); if ( arr != NULL ) { arr->length = 0; arr->points = NULL; } return(arr); } tpointarr *tpoint_buildarr(int length,tpoint *points) { tpointarr *arr=malloc(sizeof(*arr)); if ( arr != NULL ) { arr->length = length; arr->points = points; } return(arr); } void tpoint_destroyarr(tpointarr *pa) { if ( pa != NULL ) { if ( pa->points != NULL ) free(pa->points); free(pa); } return; } /* calculate eucledian distance between two 2D points */ double tpoint_eucdist(tpoint *p1,tpoint *p2) { double xx,yy; xx=p1->xcoord-p2->xcoord; yy=p1->ycoord-p2->ycoord; return(sqrt(xx*xx+yy*yy)); } /* calculate squared eucledian distance between two 2D points */ double tpoint_eucdist2(tpoint *p1, tpoint *p2) { double xx, yy; xx=p1->xcoord-p2->xcoord; yy=p1->ycoord-p2->ycoord; return(xx*xx+yy*yy); } /* return minimum in x coordinates or 0 */ double tpoint_minx(int nelem,tpoint *points) { int ii; double minx; if ( nelem < 1 || points == NULL ) return(0); minx=points[0].xcoord; for ( ii=1 ; iimaxx ) maxx=points[ii].xcoord; } return(maxx); } /* return maximum in y coordinates or 0 */ double tpoint_maxy(int nelem,tpoint *points) { int ii; double maxy; if ( nelem < 1 || points == NULL ) return(0); maxy=points[0].ycoord; for ( ii=1 ; iimaxy ) maxy=points[ii].ycoord; } return(maxy); } /* return the minimum and maximum coordinates along the x-axis */ void tpoint_minmaxx(int nelem,tpoint *points,double *minx,double *maxx) { int ii; *minx=*maxx=points->xcoord; for ( ii = 0 ; iipoints[ii].xcoord ) *minx=points[ii].xcoord; else if ( *maxxycoord; for ( ii = 0 ; iipoints[ii].ycoord ) *miny=points[ii].ycoord; else if ( *maxyxcoord; double x2=((tpoint *)p2)->xcoord; return(x2ycoord; double y2=((tpoint *)p2)->ycoord; return(y2prop; double prop2=((tpoint *)p2)->prop; return(prop2id; int prop2=((tpoint *)p2)->id; return(prop2 1 && points != NULL && idx > 0 && idx < --nelem ) { points += idx; memmove((void *)points,(void *)(points+1),(nelem-idx)*sizeof(*points)); } } /*****************************************************************************/ fitsh-0.9.2/src/math/expint/0000755000175000017500000000000012772016355014312 5ustar apalapalfitsh-0.9.2/src/math/expint/expint.h0000644000175000017500000000733010667340120015764 0ustar apalapal/*****************************************************************************/ /* expint.h */ /*****************************************************************************/ #ifndef __EXPINT_H_INCLUDED #define __EXPINT_H_INCLUDED 1 typedef struct { double exp1,exp2; double erf1,erf2; } expinte; typedef struct { double expx1,expx2,expy1,expy2; double erfx1,erfx2,erfy1,erfy2; } expintee; /* expint_numerical(), expint_taylor(), expint_taylor_ee(): Calculates the definite integral of the general elliptical Gaussian function exp[-1/2*((s+d)x^2+(s-d)y^2+k*(2xy))] on the rectangle [x1,x2]x[y1,y2]. If the calculation is successful, the desired integral is returned (which always is positive if x1 #include #include #include #include "expint.h" /*****************************************************************************/ static double expfunct(double s,double d,double k,double x,double y) { double ret; ret=exp(-0.5*((s+d)*(x*x)+(s-d)*(y*y))-k*x*y); return(ret); } double expint_numerical(double s,double d,double k,double x1,double x2,double y1,double y2) { double ret,x,y,dx,dy,w,fx,fy,dd; int n,i,j; n=1000,ret=0.0; dx=(x2-x1)/(double)n,dy=(y2-y1)/(double)n; dd=dx*dy; for ( i=0 ; i<=n ; i++ ) { for ( j=0 ; j<=n ; j++ ) { x=x1+dx*((double)j); y=y1+dy*((double)i); w=expfunct(s,d,k,x,y); if ( i==0 || i==n ) fy=1.0; else if ( i%2==1 ) fy=4.0; else fy=2.0; if ( j==0 || j==n ) fx=1.0; else if ( j%2==1 ) fx=4.0; else fx=2.0; ret+=fx*fy*w*dd; } } return(ret/9.0); } /*****************************************************************************/ double expint_taylor_ee(double s,double d,double k,double x1,double x2,double y1,double y2,expintee *ee) { double ssx,ssy,ret,retprev,iprevx,iprevy,icurrx,icurry,inextx,inexty, x1c,x2c,y1c,y2c,m; int i,n; if ( s<=0.0 || s*s-d*d-k*k<=0.0 ) return(-1.0); ssx=1.0/(s+d), ssy=1.0/(s-d); x1c=ee->expx1,x2c=ee->expx2; y1c=ee->expy1,y2c=ee->expy2; iprevx=sqrt(0.5*M_PI*ssx)*(ee->erfx2-ee->erfx1), iprevy=sqrt(0.5*M_PI*ssy)*(ee->erfy2-ee->erfy1); icurrx=-(x2c-x1c)*ssx, icurry=-(y2c-y1c)*ssy; m=-k; ret=iprevx*iprevy+m*icurrx*icurry; n=100; for ( i=1 ; i<=n ; i++ ) { x1c*=x1,x2c*=x2, y1c*=y1,y2c*=y2; inextx=((double)i*iprevx-(x2c-x1c))*ssx, inexty=((double)i*iprevy-(y2c-y1c))*ssy; m=-m*k/(double)(i+1); retprev=ret; ret+=m*inextx*inexty; if ( ret==retprev ) break; iprevx=icurrx,icurrx=inextx; iprevy=icurry,icurry=inexty; } /* fprintf(stderr,"iterations=%d\n",i); */ return(ret); } double expint_taylor(double s,double d,double k,double x1,double x2,double y1,double y2) { double cx,cy,ret; expintee ee; cx=s+d,cy=s-d; ee.expx1=exp(-0.5*cx*x1*x1),ee.erfx1=erf(sqrt(0.5*cx)*x1); ee.expx2=exp(-0.5*cx*x2*x2),ee.erfx2=erf(sqrt(0.5*cx)*x2); ee.expy1=exp(-0.5*cy*y1*y1),ee.erfy1=erf(sqrt(0.5*cy)*y1); ee.expy2=exp(-0.5*cy*y2*y2),ee.erfy2=erf(sqrt(0.5*cy)*y2); ret=expint_taylor_ee(s,d,k,x1,x2,y1,y2,&ee); return(ret); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int expint_taylor_ee_diff(double s,double d,double k,double x1,double x2,double y1,double y2,double *dlist,expintee *ee) { double ssx,ssy,iprevx,iprevy,icurrx,icurry,inextx,inexty, i0,ix,iy,ixx,ixy,iyy,i0prev,x1c,x2c,y1c,y2c,m; int i,n; if ( s<=0.0 || s*s-d*d-k*k<=0.0 ) return(-1); ssx=1.0/(s+d), ssy=1.0/(s-d); x1c=ee->expx1,x2c=ee->expx2; y1c=ee->expy1,y2c=ee->expy2; iprevx=sqrt(0.5*M_PI*ssx)*(ee->erfx2-ee->erfx1), iprevy=sqrt(0.5*M_PI*ssy)*(ee->erfy2-ee->erfy1); icurrx=-(x2c-x1c)*ssx, icurry=-(y2c-y1c)*ssy; m=1.0; i0=ix=iy=ixx=ixy=iyy=0.0; n=100; for ( i=1 ; i<=n ; i++ ) { x1c*=x1,x2c*=x2, y1c*=y1,y2c*=y2; inextx=((double)i*iprevx-(x2c-x1c))*ssx, inexty=((double)i*iprevy-(y2c-y1c))*ssy; i0prev=i0; i0+=m*iprevx*iprevy; ix+=m*icurrx*iprevy; iy+=m*iprevx*icurry; ixx+=m*inextx*iprevy; ixy+=m*icurrx*icurry; iyy+=m*iprevx*inexty; if ( i0prev==i0 ) break; m=-m*k/(double)i; iprevx=icurrx,icurrx=inextx; iprevy=icurry,icurry=inexty; } dlist[0]=i0; dlist[1]=(s+d)*ix+k*iy; dlist[2]=k*ix+(s-d)*iy; dlist[3]=-0.5*(ixx+iyy); dlist[4]=-0.5*(ixx-iyy); dlist[5]=-ixy; return(0); } int expint_taylor_ee_shift_diff(double s,double d,double k,double x0,double y0,double x1,double x2,double y1,double y2,double *dlist,expintee *ee) { return(expint_taylor_ee_diff(s,d,k,x1-x0,x2-x0,y1-y0,y2-y0,dlist,ee)); } int expint_taylor_diff(double s,double d,double k,double x1,double x2,double y1,double y2,double *dlist) { double cx,cy,mxex,mxef,myex,myef; expintee ee; cx=s+d,cy=s-d; mxex=-0.5*cx,mxef=sqrt(0.5*cx); myex=-0.5*cy,myef=sqrt(0.5*cy); ee.expx1=exp(mxex*x1*x1),ee.erfx1=erf(mxef*x1); ee.expx2=exp(mxex*x2*x2),ee.erfx2=erf(mxef*x2); ee.expy1=exp(myex*y1*y1),ee.erfy1=erf(myef*y1); ee.expy2=exp(myex*y2*y2),ee.erfy2=erf(myef*y2); return(expint_taylor_ee_diff(s,d,k,x1,x2,y1,y2,dlist,&ee)); } /*****************************************************************************/ int expint_list_e(double s,double x1,double x2,int n,double *list,expinte *e) { double ss,iprev,icurr,inext,x1c,x2c; int i; if ( s<=0.0 || list==NULL || n<0 ) return(-1); ss=1.0/(s); x1c=e->exp1,x2c=e->exp2; iprev=sqrt(0.5*M_PI*ss)*(e->erf2-e->erf1); list[0]=iprev; if ( n==0 ) return(0); icurr=-(x2c-x1c)*ss; list[1]=icurr; for ( i=1 ; i1.0 should be specified which are used by the nonlinear Levenberg-Marquardt algorithm. Also an initial assumption of the parameters 'a' have to be passed to the function. The new, hopefully better set of the parameters are stored in 'a': the routine nlm_fit_base() does overwrite the old values. Nlm_fit_base() returns a new 'lam' value, which can be passed directly to this routine in the next iteration. The returned new 'lam' value is zero, if the least-squares matrix was singular. The returned value is negative, if the routine was unable to allocate temporary memory. The optional parameter 'param' is always passed to 'funct' (arg 5). The reasonable number of interations depends on many things, on the function 'funct', on the initial parameter set 'a', on the data set 'y' (almost on everyhing). The automatic determination of the number of the interations and the values of the initial parameters 'a' is highly problem-specific. These routines use the functions matrix_alloc(), vector_alloc(), matrix_free(), vector_free() to allocate and release temporary resources. These routines also use the function solve_gauss() to solve linear equations during the fit. */ int lin_fit( void **x,double *y,double *a,double *weight, void (*funct)(void *,double *,double *,double *,void *), int n,int ndata,void *param, double *err); double nlm_fit_base( void **x,double *y,double *a,double *weight, void (*funct)(void *,double *,double *,double *,void*), int n,int ndata,void *param, double lam,double lam_mpy); typedef struct { double **cmatrix; /* constraint matrix, [0..nc-1][0..n-1] */ double *cvector; /* constraint vector, [0..nc-1] */ int nc; /* number of linear constraints */ } constraint; /* lin_fit_con(), nlm_fit_base_con(): The same as lin_fit() and nlm_fit_base(), but optional linear constraints also can be taken into account, specified by the constraint data 'cc'. If 'cc' is NULL, the call falls back to lin_fit(). */ int lin_fit_con( void **x,double *y,double *a,double *weight, void (*funct)(void *,double *,double *,double *,void *), int n,int ndata,void *param,constraint *cc, double *err); double nlm_fit_base_con(void **x,double *y,double *a,double *weight, void (*funct)(void *,double *,double *,double *,void*), int n,int ndata,void *param,constraint *cc, double lam,double lam_mpy); /* nlm_fit_nmdf_con(): The same as nlm_fit_base_con() but the partial derivatives of the function 'funct' are calculated numerically, assuming a symmetric finite difference defined by the values of 'da'. */ double nlm_fit_nmdf_con(void **x,double *y,double *a,double *weight, void (*funct)(void *,double *,double *,double *,void*), int n,int ndata,void *param,constraint *cc, double lam,double lam_mpy,double *da); /* nm_fit_nmdf(): Same as above but omitting the correlations 'cc' (equivalent to the call of nlm_fit_nmdf_con() with setting cc=NULL). */ double nlm_fit_nmdf( void **x,double *y,double *a,double *weight, void (*funct)(void *,double *,double *,double *,void*), int n,int ndata,void *param, double lam,double lam_mpy,double *da); #endif fitsh-0.9.2/src/math/fit/lmfit.c0000644000175000017500000002621011116252053015031 0ustar apalapal/*****************************************************************************/ /* lmfit.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for weighted linear and nonlinear fit of real */ /* data with a function defined on an arbitrary domain. */ /* (c) 2003, 2004, 2006; Pal, A. (apal@szofi.elte.hu). Some functions are */ /* based on the appropriate chapters of Numerical Recipes (in C) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in lmfit.h */ /*****************************************************************************/ #include #include #include #include #include "lmfit.h" /*****************************************************************************/ double **matrix_alloc_gen(int x,int y) { int i; double **m; m=(double **)malloc(sizeof(double *)*(y+1)); if ( m==NULL ) return(NULL); for ( i=0 ; i mm ) mm=-v[i]; else if ( v[i] > mm ) mm=v[i]; } if ( mm==0.0 ) return(mm); for ( i=0 ; i=0 ; i-- ) { t=b[i]; for ( j=i+1 ; j=0 ; i-- ) { for ( k=0 ; knc <= 0 ) nc=0; else nc=cc->nc; da=bvector=NULL;amatrix=NULL; da =vector_alloc(n); bvector=vector_alloc(n+nc); amatrix=matrix_alloc(n+nc); if ( da==NULL || bvector==NULL || amatrix==NULL ) { if ( da != NULL ) vector_free(da); if ( bvector != NULL ) vector_free(bvector); if ( amatrix != NULL ) matrix_free(amatrix); return(-1.0); } chi2old=0.0; for ( i=0 ; i0 && cc != NULL ) { for ( i=0 ; icvector[i]; for ( j=0 ; jcmatrix[i][j]; amatrix[j][i+n]=cc->cmatrix[i][j]; bvector[i+n]-=cc->cmatrix[i][j]*a[j]; } } } i=solve_gauss(amatrix,bvector,n+nc); if ( i ) { vector_free(da); vector_free(bvector); matrix_free(amatrix); return(0.0); } for ( i=0 ; i=chi2old ) { lambda=lambda*lambda_mpy; } else { for ( i=0 ; inc <= 0 ) nc=0; else nc=cc->nc; da=bvector=NULL;amatrix=NULL; da =vector_alloc(n); wa =vector_alloc(n); bvector=vector_alloc(n+nc); amatrix=matrix_alloc(n+nc); if ( da==NULL || bvector==NULL || amatrix==NULL ) { if ( da != NULL ) vector_free(da); if ( bvector != NULL ) vector_free(bvector); if ( amatrix != NULL ) matrix_free(amatrix); return(-1.0); } chi2old=0.0; for ( i=0 ; i0 && cc != NULL ) { for ( i=0 ; icvector[i]; for ( j=0 ; jcmatrix[i][j]; amatrix[j][i+n]=cc->cmatrix[i][j]; bvector[i+n]-=cc->cmatrix[i][j]*a[j]; } } } i=solve_gauss(amatrix,bvector,n+nc); if ( i ) { vector_free(da); vector_free(bvector); matrix_free(amatrix); return(0.0); } for ( i=0 ; i=chi2old ) { lambda=lambda*lambda_mpy; } else { for ( i=0 ; inc <= 0 ) nc=0; else nc=cc->nc; da=bvector=NULL; amatrix=ematrix=NULL; da =vector_alloc(n); bvector=vector_alloc(n+nc); amatrix=matrix_alloc(n+nc); ematrix=matrix_alloc(n); if ( da==NULL || bvector==NULL || amatrix==NULL || ematrix==NULL ) { if ( da != NULL ) vector_free(da); if ( bvector != NULL ) vector_free(bvector); if ( amatrix != NULL ) matrix_free(amatrix); if ( ematrix != NULL ) matrix_free(ematrix); return(-1); } for ( i=0 ; i0 && cc != NULL ) { for ( i=0 ; icmatrix[i][j]; amatrix[j][i+n]=cc->cmatrix[i][j]; } bvector[i+n]=cc->cvector[i]; } } for ( i=0 ; i #include #include #include #include #include "downhill.h" /*****************************************************************************/ static double downhill_simplex_amotry(double **p,double *y,double *psum, int ndim,int nvar,double (*funct)(void *param,double *arr),void *param, int ihi,double fac,double *ptry) { int j; double fac1,fac2,ytry; fac1=(1.0-fac)/(double)nvar; fac2=fac1-fac; for ( j=0 ; jy[1] ? (inhi=1,0) : (inhi=0,1) ); for ( i=0 ; i y[ihi] ) { inhi=ihi; ihi=i; } else if ( y[i] > y[inhi] && i != ihi ) inhi=i; } rtol=2.0*fabs(y[ihi]-y[ilo])/(fabs(y[ihi])+fabs(y[ilo])+1e-15); if ( rtol0 && nfunk >= maxstep ) { nfunk=-1; break; } nfunk+=2; ytry=downhill_simplex_amotry(p,y,psum,ndim,nvar,funct,param,ihi,-1.0,ptry); if ( ytry <= y[ilo] ) { ytry=downhill_simplex_amotry(p,y,psum,ndim,nvar, funct,param,ihi,2.0,ptry); } else if ( ytry >= y[inhi] ) { ysave=y[ihi]; ytry=downhill_simplex_amotry(p,y,psum,ndim,nvar, funct,param,ihi,0.5,ptry); if ( ytry>=ysave ) { for ( i=0 ; ilength-1). Note that this point (the returned one) is _not_ the nearest point, it is just a hint for further usage, e.g. cpmatch_find_nearest(). Note also that the array 'base' should be sorted (along the x-axis, in ascending order) before call. Do something like qsort((void *)base->points,base->length,sizeof(tpoint),tpoint_sortx), using the library function tpoint_sortx() of the tpoint.c module. */ int cpmatch_find_xidx(tpoint *probe,tpointarr *base); /* cpmatch_find_nearest(): Finds the point in the point array 'base' which is nearest to 'probe'. The function returns a negative number on error, otherwise it returns the array index of the matched point (which is going to be between 0 and base->length-1). The 'neighbour' is an index of a point which is probably close to 'probe'. Generally, it can be derived using cpmatch_find_xidx(). The squared distance of the 'probe' point and the matched one is returned in 'retdistance' if it was not NULL. Note that the array 'base' should be sorted (see cpmatch_find_xidx() above). */ int cpmatch_find_nearest(tpoint *probe,tpointarr *base,int neighbour, double *retdistance,int is_exclude_self); /* cpmatch_find_neighbour(): Finds the neighbour point of the 'indx'th point in the point array 'base'. If the 'indx' has a bad value of 'base' contains less than 2 points, the function returns a negative value, otherwise it returns the desired index. Like the other cpmatch_find_*() functions, the array 'base' should be sorted (see cpmatch_find_xidx() above). */ int cpmatch_find_neighbour(tpointarr *base,int indx); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* cpmatch_symmetric(): Matches two 2 dimensional point sets 'cat1' and 'cat2'. A P1 point from 'cat1' and P2 from 'cat2' are treated as matched pairs if the nearest point from 'cat2' to P1 is P2 and the nearest point from 'cat1' to P2 is P1. The function returns an array of 'cphit' object (with 'rlen' elements) which is a dynamically allocated array, can be released by free(). The parameter 'rev_sig' can be used for some post-matching rejection. If it is greater than 0, the median of the distances between the matched pairs are calculated and pairs with points farer than 'rev_sig' times the median are rejected and removed from the returned array. */ cphit *cpmatch_symmetric(tpointarr *cat1,tpointarr *cat2, int *rlen,double rev_sig,double rev_maxdist); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* cpmatch(): The original matching function written by Istvan. It is not used, obsoleted by the functions (esp. cmatch_symmetric()) above. Note that cpmatch() returns a preliminary array of pairs which should be revised (God knows how) by cphit_revise(). Ask Istvan for details... The other functions (cphit_sort_dist and cphit_sort_id) may also have to be used somewhere. */ cphit *cpmatch(tpointarr *reference,tpointarr *input,int *hlength); int cphit_sort_dist(const void *cphit1, const void *cphit2); int cphit_sort_id(const void *cphit1, const void *cphit2); int cphit_revise(int hlen,cphit **hits, int maxarrlen, cpmtype matchtype,double *maxdist); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/math/poly.h0000644000175000017500000000603410667340117014137 0ustar apalapal/*****************************************************************************/ /* poly.h */ /*****************************************************************************/ #ifndef __POLY_H_INCLUDED #define __POLY_H_INCLUDED 1 /* eval_2d_monoms(): Evaluates 2 dimensional monomials up to order 'order' in the point (x,y). Before the evaluation, the point (x,y) is shifted and rescaled using the parameters 'ox', 'oy' and 'scale'. Not to perform such shift and scaling, set ox=oy=0.0 and scale=1.0. The monoms are returned in the array 'ret' where should be enough space for the monomials. Up to order 'order', there are (order+1)*(order+2)/2 monomials. For example, if 'order' is 3, the array 'ret' has the following elements: ret[0]=1.0 ret[1]=x'^1/1! ret[2]=y'^1/1! ret[3]=x'^2/2! ret[4]=x'^1/1!*y'^1/1! ret[5]=y'^2/2! ret[6]=x'^3/3! ret[7]=x'^2/2!*y'^1/1! ret[8]=x'^1/1!*y'^2/2! ret[9]=y'^3/3!, where x'=(x-ox)/scale and y'=(y-oy)/scale. */ int eval_2d_monoms( double x,double y,int order,double *ret , double ox,double oy,double scale); /* eval_2d_poly(): Evaluates a 2 dimensional polynomial up to order 'order' in the point (x,y) using the coefficients 'coeff'. Before the evaluation, the point (x,y) is shifted and rescaled using the parameters 'ox', 'oy' and 'scale'. */ double eval_2d_poly ( double x,double y,int order,double *coeff, double ox,double oy,double scale); /* eval_2d_leg_monoms(): Evaluates 2 dimensional Legendre monomials up to order 'order' in the point (x,y). See also eval_2d_monoms(). */ int eval_2d_leg_monoms( double x,double y,int order,double *ret, double ox,double oy,double scale); /* eval_2d_leg_poly(): Evaluates a 2 dimensional Legendre polynomial up to order 'order' in the point (x,y). See also eval_2d_poly(). */ double eval_2d_leg_poly(double x,double y,int order,double *coeff, double ox,double oy,double scale); /* diff_2d_poly(): Calculates the derivative polynomial of the polynom described by the coefficients 'coeff' (up to order 'order'). The calculated derivatives are stored in 'dxcoeff' and 'dycoeff' if they are not NULL. Note that the resulted polynomials have an order 'order'-1, therefore they have less coefficients. */ int diff_2d_poly(double *coeff,int order,double *dxcoeff,double *dycoeff); /* compose_2d_poly_with_affine(): Composes the polynomial described by the 'coeff' coefficients (up to order 'order') with the affine transformation stored in xlin[0],[1],[2] and ylin[0],[1],[2]. The coefficients of the new polynomial is stored in 'rc'. */ int compose_2d_poly_with_affine(double *coeff,int order, double *xlin,double *ylin,double *rc); /* calc_2d_unitarity(): Calculates the unitarity of the 2d->2d transformation described by the coefficients 'xfit' and 'yfit' up to the order 'order'. */ double calc_2d_unitarity(double *xfit,double *yfit,int order); #endif fitsh-0.9.2/src/math/polyfit.c0000644000175000017500000001046011116252010014613 0ustar apalapal/*****************************************************************************/ /* polyfit.c [-> poly.c,lmfit.c,point.h] */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* A library for fitting polynomials in R^2 (in a plane). */ /* The library is NOT standalone, it needs functions from lmfit.c and poly.c */ /* (c) 2001, 2004, 2005; Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in polyfit.h */ /*****************************************************************************/ #include #include #include #include #include "fit/lmfit.h" #include "poly.h" #include "point.h" #include "polyfit.h" /*****************************************************************************/ static int fit_poly_alloc_arrays(int nvar,double **rfvars,double **rbvector,double ***ramatrix) { int i,j; *rfvars=vector_alloc(nvar); if ( *rfvars==NULL ) { return(1); } *rbvector=vector_alloc(nvar); if ( *rbvector==NULL ) { vector_free(*rfvars); return(1); } *ramatrix=matrix_alloc(nvar); if ( *ramatrix==NULL ) { vector_free(*rfvars); vector_free(*rbvector); return(1); } for ( i=0 ; i /*****************************************************************************/ #define O_ADD 1 /* + */ #define O_SUB 2 /* - */ #define O_MUL 3 /* * */ #define O_DIV 4 /* / */ #define O_POW 5 /* ^ */ #define O_CHS 6 /* change sign, unary variant of '-' */ #define O_RCP 7 /* Reciprocal // these two */ #define O_PSQ 8 /* Square (power) // have no symbol */ #define O_EQU 10 #define O_NEQ 11 #define O_LS 12 #define O_GR 13 #define O_LE 14 #define O_GE 15 #define O_AND 20 #define O_OR 21 /* Basic functions */ #define F_SIN 32 #define F_COS 33 #define F_TAN 34 #define F_CTN 35 #define F_SINA 36 #define F_COSA 37 #define F_TANA 38 #define F_CTNA 39 #define F_ASIN 40 #define F_ACOS 41 #define F_ATAN 42 #define F_ACTN 43 #define F_ASINA 44 #define F_ACOSA 45 #define F_ATANA 46 #define F_ACTNA 47 #define F_EXP 48 #define F_LOG 49 #define F_EXP10 50 #define F_LOG10 51 #define F_SQR 52 #define F_ABS 53 #define F_SGN 54 #define F_FMOD 55 #define F_FINT 56 #define F_FDIV 57 #define F_ARG 58 #define F_VPI 59 #define F_RND 60 #define F_GAUSS 61 /*****************************************************************************/ extern psnsym psn_general_op[]; extern psnsym psn_general_xop[]; extern psnsym psn_general_fn[]; extern psnsym psn_general_fn_rnd[]; extern psnprop psn_general_prop[]; extern psnfunct psn_general_funct[]; /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/psn/psn-general-ds.c0000644000175000017500000002161411236246443015636 0ustar apalapal/*****************************************************************************/ /* psn-general-ds.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* A simple set of general, widely used functions and operators: */ /* +, -, *, /, ^ (power) */ /* sin, cos, tan, ctn (argument is in radians) */ /* sina, cosa, tana, ctna (argument is in degrees) */ /* exp, ln (log), (natural exp() and log()) */ /* sqrt, abs, sign, mod, pi (some other functions) */ /* These file contains simplification and differentation rules. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2002-2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include "psn-general.h" #include "psn-general-ds.h" /* Derivative rules **********************************************************/ static short diffrule_o_add[]={ SS_D2,SS_D1,O_ADD,0 }; static short diffrule_o_sub[]={ SS_D2,SS_D1,O_SUB,0 }; static short diffrule_o_mul[]={ SS_D2,SS_N1,O_MUL,SS_D1,SS_N2,O_MUL,O_ADD,0 }; static short diffrule_o_div[]={ SS_D2,SS_N1,O_MUL,SS_D1,SS_N2,O_MUL,O_SUB,SS_N1,O_PSQ,O_DIV,0 }; static short diffrule_o_pow[]={ SS_N2,SS_N1,O_POW,SS_D1,O_MUL,SS_N2,F_LOG,O_MUL,SS_N2,SS_N1,CON_1,O_SUB,O_POW,SS_N1,O_MUL,SS_D2,O_MUL,O_ADD,0 }; static short diffrule_o_chs[]={ SS_D1,O_CHS,0 }; static short diffrule_o_psq[]={ SS_N1,CON_2,O_MUL,SS_D1,O_MUL,0 }; static short diffrule_o_rcp[]={ SS_N1,O_PSQ,O_RCP,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_sqr[]={ SS_N1,F_SQR,CON_2,O_MUL,O_RCP,SS_D1,O_MUL,0 }; static short diffrule_f_abs[]={ SS_N1,F_SGN,SS_D1,O_MUL,0 }; static short diffrule_f_sgn[]={ CON_0,0 }; /* static short diffrule_f_fmod[]={ SS_D2,SS_N2,SS_N1,F_FMOD,SS_N1,O_DIV,SS_N2,SS_N1,O_PSQ,O_DIV,O_SUB,SS_D1,O_MUL,O_ADD,0 }; */ static short diffrule_f_fmod[]={ SS_D2,SS_N2,SS_N1,O_DIV,F_FINT,SS_D1,O_MUL,O_SUB,0 }; static short diffrule_f_fint[]={ CON_0,0 }; static short diffrule_f_vpi[]={ CON_0,0 }; static short diffrule_f_arg[]={ SS_N2,SS_D1,O_MUL,SS_N1,SS_D2,O_MUL,O_SUB,SS_N1,O_PSQ,SS_N2,O_PSQ,O_ADD,O_DIV,0 }; static short diffrule_f_sin[]={ SS_N1,F_COS,SS_D1,O_MUL,0 }; static short diffrule_f_cos[]={ SS_N1,F_SIN,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_tan[]={ SS_N1,F_COS,O_PSQ,O_RCP,SS_D1,O_MUL,0 }; static short diffrule_f_ctn[]={ SS_N1,F_SIN,O_PSQ,O_RCP,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_sina[]={ SS_N1,F_COS,SS_D1,O_MUL,0 }; static short diffrule_f_cosa[]={ SS_N1,F_SIN,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_tana[]={ SS_N1,F_COS,O_PSQ,O_RCP,SS_D1,O_MUL,0 }; static short diffrule_f_ctna[]={ SS_N1,F_SIN,O_PSQ,O_RCP,O_CHS,SS_D1,O_MUL,0 }; static short diffrule_f_exp[]={ SS_N1,F_EXP,SS_D1,O_MUL,0 }; static short diffrule_f_log[]={ SS_N1,O_RCP,SS_D1,O_MUL,0 }; psndiff psn_general_diff[]={ {O_ADD ,diffrule_o_add}, {O_SUB ,diffrule_o_sub}, {O_MUL ,diffrule_o_mul}, {O_DIV ,diffrule_o_div}, {O_POW ,diffrule_o_pow}, {O_CHS ,diffrule_o_chs}, {O_PSQ ,diffrule_o_psq}, {O_RCP ,diffrule_o_rcp}, {F_SQR ,diffrule_f_sqr}, {F_ABS ,diffrule_f_abs}, {F_SGN ,diffrule_f_sgn}, {F_FMOD,diffrule_f_fmod}, {F_FINT,diffrule_f_fint}, {F_VPI ,diffrule_f_vpi}, {F_ARG ,diffrule_f_arg}, {F_SIN ,diffrule_f_sin}, {F_COS ,diffrule_f_cos}, {F_TAN ,diffrule_f_tan}, {F_CTN ,diffrule_f_ctn}, {F_SINA,diffrule_f_sina}, {F_COSA,diffrule_f_cosa}, {F_TANA,diffrule_f_tana}, {F_CTNA,diffrule_f_ctna}, {F_EXP ,diffrule_f_exp}, {F_LOG ,diffrule_f_log}, {0,NULL} }; /* Simplifying rules *********************************************************/ /* Type */ static short sim_o_add1[]={ S_EXP1,CON_0,O_ADD,0,S_EXP1,0 }; /* expr+0=expr */ static short sim_o_add2[]={ CON_0,S_EXP1,O_ADD,0,S_EXP1,0 }; /* 0+expr=expr */ static short sim_o_sub1[]={ S_EXP1,CON_0,O_SUB,0,S_EXP1,0 }; /* expr-0=expr */ static short sim_o_sub2[]={ CON_0,S_EXP1,O_SUB,0,S_EXP1,O_CHS,0 }; /* 0-expr=-expr */ static short sim_o_mul1[]={ S_EXP1,CON_1 ,O_MUL,0,S_EXP1,0 }; /* expr*1=expr */ static short sim_o_mul2[]={ CON_1 ,S_EXP1,O_MUL,0,S_EXP1,0 }; /* 1*expr=expr */ static short sim_o_mul3[]={ S_EXP1,CON_0 ,O_MUL,0,CON_0,0 }; /* expr*0=0 */ static short sim_o_mul4[]={ CON_0 ,S_EXP1,O_MUL,0,CON_0,0 }; /* 0*expr=0 */ static short sim_o_mul5[]={ S_EXP1,S_EXP1,O_MUL,0,S_EXP1,O_PSQ,0 }; /* ex*ex=ex^(2) */ static short sim_o_div1[]={ S_EXP1,CON_1 ,O_DIV,0,S_EXP1,0 }; /* expr/1=expr */ static short sim_o_div2[]={ CON_1 ,S_EXP1,O_DIV,0,S_EXP1,O_RCP,0 }; /* 1/expr=expr^(-1) */ static short sim_o_div3[]={ S_EXP1,CON_0 ,O_DIV,0,0 }; /* expr/0=UNDEF! */ static short sim_o_div4[]={ CON_0 ,S_EXP1,O_DIV,0,CON_0 ,0 }; /* 0/expr=0 */ static short sim_o_pow1[]={ S_EXP1,CON_0,O_POW,0,CON_1 ,0 }; /* ex^0=1 */ static short sim_o_pow2[]={ S_EXP1,CON_1,O_POW,0,S_EXP1,0 }; /* ex^1=ex */ static short sim_o_pow3[]={ S_EXP1,CON_2,O_POW,0,S_EXP1,O_PSQ,0 }; /* ex^2=ex PSQ */ static short sim_addmul_dis1[]={ S_EXP1,S_EXP2,O_MUL,S_EXP1,S_EXP3,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* a*b+a*c=a*(b+c) */ static short sim_addmul_dis2[]={ S_EXP2,S_EXP1,O_MUL,S_EXP1,S_EXP3,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* a*b+c*a=a*(b+c) */ static short sim_addmul_dis3[]={ S_EXP1,S_EXP2,O_MUL,S_EXP3,S_EXP1,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* b*a+a*c=a*(b+c) */ static short sim_addmul_dis4[]={ S_EXP2,S_EXP1,O_MUL,S_EXP3,S_EXP1,O_MUL,O_ADD,0,S_EXP1,S_EXP2,S_EXP3,O_ADD,O_MUL,0 }; /* b*a+c*a=a*(b+c) */ static short sim_submul_dis1[]={ S_EXP1,S_EXP2,O_MUL,S_EXP1,S_EXP3,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* a*b-a*c=a*(b-c) */ static short sim_submul_dis2[]={ S_EXP2,S_EXP1,O_MUL,S_EXP1,S_EXP3,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* a*b-c*a=a*(b-c) */ static short sim_submul_dis3[]={ S_EXP1,S_EXP2,O_MUL,S_EXP3,S_EXP1,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* b*a-a*c=a*(b-c) */ static short sim_submul_dis4[]={ S_EXP2,S_EXP1,O_MUL,S_EXP3,S_EXP1,O_MUL,O_SUB,0,S_EXP1,S_EXP2,S_EXP3,O_SUB,O_MUL,0 }; /* b*a-c*a=a*(b-c) */ static short sim_adddiv_dis []={ S_EXP2,S_EXP1,O_DIV,S_EXP3,S_EXP1,O_DIV,O_ADD,0,S_EXP2,S_EXP3,O_ADD,S_EXP1,O_DIV,0 }; /* b/a+c/a=(b+c)/a */ static short sim_subdiv_dis []={ S_EXP2,S_EXP1,O_DIV,S_EXP3,S_EXP1,O_DIV,O_SUB,0,S_EXP2,S_EXP3,O_SUB,S_EXP1,O_DIV,0 }; /* b/a-c/a=(b-c)/a */ static short sim_mulpow_dis []={ S_EXP2,S_EXP1,O_POW,S_EXP3,S_EXP1,O_POW,O_MUL,0,S_EXP2,S_EXP3,O_MUL,S_EXP1,O_POW,0 }; /* b^a*c^a=(b*c)^a */ static short sim_divpow_dis []={ S_EXP2,S_EXP1,O_POW,S_EXP3,S_EXP1,O_POW,O_DIV,0,S_EXP2,S_EXP3,O_DIV,S_EXP1,O_POW,0 }; /* b^a/c^a=(b/c)^a */ static short sim_tau1[]= { S_EXP1,S_EXP2,O_CHS,O_SUB,0,S_EXP1,S_EXP2,O_ADD,0 }; /* a-(-b)=a+b */ static short sim_gon1[]= { S_EXP1,F_SIN,O_PSQ,S_EXP1,F_COS,O_PSQ,O_ADD,0,CON_1,0 }; /* sin^2(x)+cos^2(x)=1 */ short *psn_general_simp[]= { sim_o_add1,sim_o_add2,sim_o_sub1,sim_o_sub2, sim_o_mul1,sim_o_mul2,sim_o_mul3,sim_o_mul4,sim_o_mul5, sim_o_div1,sim_o_div2,sim_o_div3,sim_o_div4, sim_o_pow1,sim_o_pow2,sim_o_pow3, sim_addmul_dis1,sim_addmul_dis2,sim_addmul_dis3,sim_addmul_dis4, sim_submul_dis1,sim_submul_dis2,sim_submul_dis3,sim_submul_dis4, sim_adddiv_dis,sim_subdiv_dis,sim_mulpow_dis,sim_divpow_dis, sim_tau1,sim_gon1, NULL }; /* Symbolic rules ************************************************************/ psnsymeval psn_general_symeval[] = { { 0 , "(#0)", 1,0 }, { O_ADD, "#(1)+#(2)", 0,TO_INFIX }, { O_SUB, "#(1)-#[2]", 0,TO_INFIX }, { O_CHS, "(-#(1))", 1,0 }, { O_MUL, "#(1)*#(2)", 0,TO_INFIX }, { O_DIV, "#(1)/#[2]", 0,TO_INFIX }, { O_POW, "#(1)^#(2)", 1,0 }, { O_RCP, "1.0/#[1]", 0,TO_INFIX }, { O_PSQ, "#(1)^2", 1,0 }, { F_SIN, "sin(#1)", 1,0 }, { F_COS, "cos(#1)", 1,0 }, { F_TAN, "tg(#1)", 1,0 }, { F_CTN, "ctg(#1)", 1,0 }, { F_SINA, "sina(#1)", 1,0 }, { F_COSA, "cosa(#1)", 1,0 }, { F_TANA, "tga(#1)", 1,0 }, { F_CTNA, "ctga(#1)", 1,0 }, { F_ASIN, "asin(#1)", 1,0 }, { F_ACOS, "acos(#1)", 1,0 }, { F_ATAN, "atan(#1)", 1,0 }, { F_ACTN, "actn(#1)", 1,0 }, { F_ASINA, "asina(#1)", 1,0 }, { F_ACOSA, "acosa(#1)", 1,0 }, { F_ATANA, "atana(#1)", 1,0 }, { F_ACTNA, "actna(#1)", 1,0 }, { F_EXP, "exp(#1)", 1,0 }, { F_LOG, "log(#1)", 1,0 }, { F_EXP, "exp10(#1)", 1,0 }, { F_LOG, "log10(#1)", 1,0 }, { F_SQR, "sqrt(#1)", 1,0 }, { F_ABS, "abs(#1)", 1,0 }, { F_SGN, "sign(#1)", 1,0 }, { F_FMOD, "mod(#1,#2)", 2,0 }, { F_FINT, "int(#1)", 1,0 }, { F_FDIV, "div(#1,#2)", 2,0 }, { F_VPI, "pi()", 0,0 }, { 0, NULL,0,0 } }; /*****************************************************************************/ fitsh-0.9.2/src/psn/Makefile.in0000644000175000017500000000056611657564540014733 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ INC=../../include CFLAGS=@CFLAGS@ -I$(INC) .PHONY: all clean all: psn-general.o psn-general-ds.o psn-general.o: psn-general.c psn-general.h $(CC) $(CFLAGS) -c psn-general.c psn-general-ds.o: psn-general-ds.c psn-general-ds.h psn-general.h $(CC) $(CFLAGS) -c psn-general-ds.c clean: rm -f *.o *.a $(TARGETS) fitsh-0.9.2/src/psn/psn-general.c0000644000175000017500000002537011657745301015241 0ustar apalapal/*****************************************************************************/ /* psn-general.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* A simple set of general, widely used functions and operators: */ /* +, -, *, /, ^ (power) */ /* sin, cos, tan, ctn (argument is in radians) */ /* sina, cosa, tana, ctna (argument is in degrees) */ /* exp, ln (log), expt, lg (natural and 10-based exp() and log()) */ /* sqrt, abs, sign, mod, int, div, pi (some other functions) */ /* ==, !=, <, >, <=, >=, &&, || (relation and logical operators) */ /* r, g (functions related to random number generation) */ /* These file contaions symbol definitions and evaluating function codes. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2002-2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include "psn-general.h" /* Definition of operators, basic symbols and functions, basic precedencies **/ /* and unary operators which have binary symbols also... *********************/ psnsym psn_general_op[]= { { T_OP, O_ADD, "+", TO_INFIX }, { T_OP, 0 , "+", TO_PREFIX }, { T_OP, O_SUB, "-", TO_INFIX }, { T_OP, O_CHS, "-", TO_PREFIX }, { T_OP, O_MUL, "*", TO_INFIX }, { T_OP, O_DIV, "/", TO_INFIX }, { T_OP, O_POW, "^", TO_INFIX }, { T_OP, O_RCP, "RCP", 0 }, { T_OP, O_PSQ, "PSQ", 0 }, {0,0,NULL,0} }; psnsym psn_general_xop[]= { { T_OP, O_EQU, "==", TO_INFIX }, { T_OP, O_NEQ, "!=", TO_INFIX }, { T_OP, O_LS , "<" , TO_INFIX }, { T_OP, O_GR , ">" , TO_INFIX }, { T_OP, O_LE , "<=", TO_INFIX }, { T_OP, O_GE , ">=", TO_INFIX }, { T_OP, O_AND, "&&", TO_INFIX }, { T_OP, O_OR , "||", TO_INFIX }, {0,0,NULL,0} }; psnsym psn_general_fn[]= { { T_FN, F_SIN , "sin" ,1 }, { T_FN, F_COS , "cos" ,1 }, { T_FN, F_TAN , "tg" ,1 }, { T_FN, F_TAN , "tan" ,1 }, { T_FN, F_CTN , "ctg" ,1 }, { T_FN, F_CTN , "ctn" ,1 }, { T_FN, F_SINA , "sina",1 }, { T_FN, F_COSA , "cosa",1 }, { T_FN, F_TANA , "tga",1 }, { T_FN, F_TANA , "tana",1 }, { T_FN, F_CTNA , "ctga",1 }, { T_FN, F_CTNA , "ctna",1 }, { T_FN, F_ASIN, "arcsin",1 }, { T_FN, F_ASIN, "asin",1 }, { T_FN, F_ACOS, "arccos",1 }, { T_FN, F_ACOS, "acos",1 }, { T_FN, F_ATAN, "arctg" ,1 }, { T_FN, F_ATAN, "atan",1 }, { T_FN, F_ACTN, "arcctg",1 }, { T_FN, F_ACTN, "actan",1 }, { T_FN, F_ASINA, "arcsina",1 }, { T_FN, F_ASINA, "asina",1 }, { T_FN, F_ACOSA, "arccosa",1 }, { T_FN, F_ACOSA, "acosa",1 }, { T_FN, F_ATANA, "arctga" ,1 }, { T_FN, F_ATANA, "atana",1 }, { T_FN, F_ACTNA, "arcctga",1 }, { T_FN, F_ACTNA, "actana",1 }, { T_FN, F_EXP , "exp" ,1 }, { T_FN, F_LOG , "ln" ,1 }, { T_FN, F_LOG , "log" ,1 }, { T_FN, F_EXP10, "expt",1 }, { T_FN, F_LOG10, "lg" ,1 }, { T_FN, F_EXP10, "exp10",1 }, { T_FN, F_LOG10, "log10",1 }, { T_FN, F_SQR , "sqrt",1 }, { T_FN, F_ABS , "abs" ,1 }, { T_FN, F_SGN , "sign",1 }, { T_FN, F_FMOD , "mod" ,2 }, { T_FN, F_FINT , "int" ,1 }, { T_FN, F_FDIV , "div" ,2 }, { T_FN, F_VPI , "pi" ,0 }, { T_FN, F_ARG , "arg" ,2 }, { 0,0,NULL,0 } }; psnsym psn_general_fn_rnd[]= { { T_FN, F_RND , "r",2 }, { T_FN, F_GAUSS, "g",2 }, { 0,0,NULL,0 } }; /* Precedence & associativity definitions ************************************/ psnprop psn_general_prop[] = { { O_ADD, 2, 20, ASSOC_LEFT }, { O_SUB, 2, 20, ASSOC_LEFT }, { O_MUL, 2, 21, ASSOC_LEFT }, { O_DIV, 2, 21, ASSOC_LEFT }, { O_CHS, 1, 22 }, { O_POW, 2, 23, ASSOC_RIGHT }, { O_RCP, 1, 23 }, { O_PSQ, 1, 23 }, { O_EQU, 2, 10, ASSOC_LEFT }, { O_NEQ, 2, 10, ASSOC_LEFT }, { O_LS , 2, 10, ASSOC_LEFT }, { O_GR , 2, 10, ASSOC_LEFT }, { O_LE , 2, 10, ASSOC_LEFT }, { O_GE , 2, 10, ASSOC_LEFT }, { O_AND, 2, 5, ASSOC_LEFT }, { O_OR , 2, 4, ASSOC_LEFT }, { F_SIN ,1, 0 }, { F_COS ,1, 0 }, { F_TAN ,1, 0 }, { F_TAN ,1, 0 }, { F_CTN ,1, 0 }, { F_CTN ,1, 0 }, { F_SINA ,1, 0 }, { F_COSA ,1, 0 }, { F_TANA ,1, 0 }, { F_TANA ,1, 0 }, { F_CTNA ,1, 0 }, { F_CTNA ,1, 0 }, { F_EXP ,1, 0 }, { F_LOG ,1, 0 }, { F_EXP10,1, 0 }, { F_LOG10,1, 0 }, { F_SQR ,1, 0 }, { F_ABS ,1, 0 }, { F_SGN ,1, 0 }, { F_FMOD ,2, 0 }, { F_FINT ,1, 0 }, { F_FDIV ,2, 0 }, { F_VPI ,0, 0 }, { F_ARG ,2, 0 }, { F_RND ,2, 0 }, { F_GAUSS,2, 0 }, { 0, 0, 0, 0 } }; /* Definition of function codes **********************************************/ static int __fn_o_add(double *s) { *(s-2)=(*(s-2))+(*(s-1));return(0); } static int __fn_o_sub(double *s) { *(s-2)=(*(s-2))-(*(s-1));return(0); } static int __fn_o_mul(double *s) { *(s-2)=(*(s-2))*(*(s-1));return(0); } static int __fn_o_div(double *s) { if ( *(s-1)==0.0 ) return(1); *(s-2)=(*(s-2))/(*(s-1));return(0); } static int __fn_o_pow(double *s) { /* if ( *(s-2)<=0.0 ) return(1); */ *(s-2)=pow(*(s-2),*(s-1)); return(0); } static int __fn_o_chs(double *s) { *(s-1)=-(*(s-1));return(0); } static int __fn_o_psq(double *s) { s--,(*s)*=*s;return(0); } static int __fn_o_rcp(double *s) { s--;if ( *s==0.0 ) return(1); *s=1.0/(*s);return(0); } static int __fn_o_sqr(double *s) { s--;if ( *s<0.0 ) return(1); *s=sqrt(*s);return(0); } static int __fn_o_abs(double *s) { s--;*s=fabs(*s);return(0); } static int __fn_o_sgn(double *s) { s--; if ( *s>0 ) *s=1.0; else if ( *s<0 ) *s=-1.0; else *s=0.0; return(0); } static int __fn_o_fmod(double *s) { double m,d;int k; s-=2;m=*s,d=*(s+1); if ( d<0.0 ) d=-d; else if ( d==0.0 ) return(1); if ( m<0.0 ) k=(int)((-m)/d),m+=d*(double)(k+2); k=(int)(m/d),m-=(double)k*d; *s=m;return(0); } static int __fn_o_fint(double *s) { s--;*s=floor(*s);return(0); } static int __fn_o_fdiv(double *s) { double m,d; s-=2;m=*s,d=*(s+1); if ( d<0.0 ) d=-d; else if ( d==0.0 ) return(1); m=floor(m/d); *s=m;return(0); } #define X_PI 3.1415926535897932 static int __fn_o_vpi(double *s) { *s=X_PI;return(0); } static int __fn_f_arg(double *s) { s-=2; *s=atan2(*(s+1),*s);return(0); } static int __fn_f_exp(double *s) { s--;*s=exp(*s);return(0); } static int __fn_f_log(double *s) { s--;if ( *s<=0.0 ) return(1); *s=log(*s);return(0); } static int __fn_f_exp10(double *s) { s--;*s=exp(*s*(M_LN10));return(0); } static int __fn_f_log10(double *s) { s--;if ( *s<=0.0 ) return(1); *s=log(*s)*M_LOG10E;return(0); } static int __fn_f_sin(double *s) { *(s-1)=sin(*(s-1));return(0); } static int __fn_f_cos(double *s) { *(s-1)=cos(*(s-1));return(0); } static int __fn_f_tan(double *s) { *(s-1)=tan(*(s-1));return(0); } static int __fn_f_ctn(double *s) { *(s-1)=1.0/tan(*(s-1));return(0); } static int __fn_f_sina(double *s) { *(s-1)=sin(*(s-1)*X_PI/180.0);return(0); } static int __fn_f_cosa(double *s) { *(s-1)=cos(*(s-1)*X_PI/180.0);return(0); } static int __fn_f_tana(double *s) { *(s-1)=tan(*(s-1)*X_PI/180.0);return(0); } static int __fn_f_ctna(double *s) { *(s-1)=1.0/tan(*(s-1)*X_PI/180.0);return(0); } static int __fn_f_asin(double *s) { *(s-1)=asin(*(s-1));return(0); } static int __fn_f_acos(double *s) { *(s-1)=acos(*(s-1));return(0); } static int __fn_f_atan(double *s) { *(s-1)=atan(*(s-1));return(0); } static int __fn_f_actn(double *s) { *(s-1)=atan(1.0/(*(s-1)));return(0); } static int __fn_f_asina(double *s) { *(s-1)=asin(*(s-1))*180.0/X_PI;return(0); } static int __fn_f_acosa(double *s) { *(s-1)=acos(*(s-1))*180.0/X_PI;return(0); } static int __fn_f_atana(double *s) { *(s-1)=atan(*(s-1))*180.0/X_PI;return(0); } static int __fn_f_actna(double *s) { *(s-1)=atan(1.0/(*(s-1)))*180.0/X_PI;return(0); } /* Definitions of additional operators: relations and boolean operators: *****/ static int __fn_o_equ(double *s) { if ( *(s-1)==*(s-2) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int __fn_o_neq(double *s) { if ( *(s-1)!=*(s-2) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int __fn_o_ls(double *s) { if ( *(s-2)< *(s-1) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int __fn_o_gr(double *s) { if ( *(s-2)> *(s-1) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int __fn_o_le(double *s) { if ( *(s-2)<=*(s-1) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int __fn_o_ge(double *s) { if ( *(s-2)>=*(s-1) ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int __fn_o_and(double *s) { if ( *(s-1)!=0 && *(s-2)!=0 ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } static int __fn_o_or(double *s) { if ( *(s-1)!=0 || *(s-2)!=0 ) *(s-2)=1.0; else *(s-2)=0.0; return(0); } /* Definitions of functions related to generate random numbers: **************/ static int __fn_f_rnd (double *s) { *(s-2)=*(s-2)+(*(s-1)-*(s-2))*random_double();return(0); } static int __fn_f_gauss(double *s) { *(s-2)=*(s-2)+(*(s-1))*sqrt(-2.0*log(random_double()))*cos(2.0*X_PI*random_double());return(0); } /*****************************************************************************/ psnfunct psn_general_funct[] = { { O_ADD,__fn_o_add}, { O_SUB,__fn_o_sub}, { O_MUL,__fn_o_mul}, { O_DIV,__fn_o_div}, { O_POW,__fn_o_pow}, { O_CHS,__fn_o_chs}, { O_PSQ,__fn_o_psq}, { O_RCP,__fn_o_rcp}, { F_SQR,__fn_o_sqr}, { F_ABS,__fn_o_abs}, { F_SGN,__fn_o_sgn}, { F_FMOD,__fn_o_fmod}, { F_FINT,__fn_o_fint}, { F_FDIV,__fn_o_fdiv}, { F_VPI,__fn_o_vpi}, { F_ARG,__fn_f_arg}, { F_EXP,__fn_f_exp}, { F_LOG,__fn_f_log}, { F_EXP10,__fn_f_exp10}, { F_LOG10,__fn_f_log10}, { F_SIN,__fn_f_sin}, { F_COS,__fn_f_cos}, { F_TAN,__fn_f_tan}, { F_CTN,__fn_f_ctn}, { F_SINA,__fn_f_sina}, { F_COSA,__fn_f_cosa}, { F_TANA,__fn_f_tana}, { F_CTNA,__fn_f_ctna}, { F_ASIN ,__fn_f_asin }, { F_ACOS ,__fn_f_acos }, { F_ATAN ,__fn_f_atan }, { F_ACTN ,__fn_f_actn }, { F_ASINA,__fn_f_asina}, { F_ACOSA,__fn_f_acosa}, { F_ATANA,__fn_f_atana}, { F_ACTNA,__fn_f_actna}, { O_EQU,__fn_o_equ}, { O_NEQ,__fn_o_neq}, { O_LS ,__fn_o_ls}, { O_GR ,__fn_o_gr}, { O_LE ,__fn_o_le}, { O_GE ,__fn_o_ge}, { O_AND,__fn_o_and}, { O_OR ,__fn_o_or}, { F_RND ,__fn_f_rnd }, { F_GAUSS,__fn_f_gauss}, {0,NULL} }; /*****************************************************************************/ fitsh-0.9.2/src/psn/psn-general-ds.h0000644000175000017500000000127410667340124015641 0ustar apalapal/*****************************************************************************/ /* psn-general-ds.h */ /*****************************************************************************/ #ifndef __PSN_GENERAL_DS_H_INCLUDED #define __PSN_GENERAL_DS_H_INCLUDED 1 /*****************************************************************************/ extern psndiff psn_general_diff[]; extern short * psn_general_simp[]; extern psnsymeval psn_general_symeval[]; /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/psf-determine.h0000644000175000017500000000420511236250067014760 0ustar apalapal/*****************************************************************************/ /* psf-determine.h */ /*****************************************************************************/ #ifndef __PSF_DETERMINE_H_INCLUDED #define __PSF_DETERMINE_H_INCLUDED 1 #include /* typedef: fits, fitsimage */ #include "psf.h" /* typedef: psf */ #include "stars.h" /* typedef: candidate */ /*****************************************************************************/ #define PSF_DET_NATIVE 1 #define PSF_DET_INTEGRAL 2 #define PSF_DET_CIRCLE 3 typedef struct { int use_biquad; } psfdeterminenative; typedef struct { double kappa; } psfdetermineintegral; typedef struct { double width; int order; } psfdeterminecircle; typedef union { psfdeterminenative native; psfdetermineintegral integral; psfdeterminecircle circle; } psfdetparam; typedef struct { int type; int hsize,grid; int order; psfdetparam param; int is_symmetrize; } psfdetermine; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int psf_determine_native (fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, int hsize,int grid,int order,psf *p,int use_biquad); int psf_determine_integral(fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, int hsize,int grid,int order,psf *p,double kappa); int psf_determine_circle (fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, int hsize,int grid,int order,psf *p,double circwd,int circorder); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int psf_determine(fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, psfdetermine *pd,psf *p); int drawback_psf(ipoint *ipoints,int nipoint,double *yvals, double x0,double y0,double amp,psf *p,double mul); int psf_bgamp_fit(fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted,psf *p); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/longhelp.c0000644000175000017500000001505712766335607014045 0ustar apalapal/*****************************************************************************/ /* longhelp.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Copyright (C) 2008; Pal, A. (apal@szofi.elte.hu) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions for creating nice ``long helps''. Output is intented to be */ /* compatible with the `help2man` utility. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This library 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 the program. If not, see . */ /*****************************************************************************/ #include #include #include #include #include #include #ifndef HOST_WIN32 #include #endif #include "longhelp.h" #ifdef HAVE_LIBINTL_H #include #define _(string) gettext(string) #else #define _(string) string #endif /*****************************************************************************/ #define LONGHELP_ABORT_ON_MALLOC #ifdef LONGHELP_ABORT_ON_MALLOC #define realloc_check(ptr,size) \ do \ { if ( ptr==NULL && size>0 ) \ { fprintf(stderr,"tokenize.c: %s.\n",_("memory exhausted"));\ abort(); \ } \ } while(0) #else #define realloc_check(ptr,size) #endif #define malloc_check(ptr) realloc_check(ptr,1) /*****************************************************************************/ static void remove_quotes(char *buff) { int k; while ( *buff ) { for ( k=0 ; buff[k]=='"' ; ) k++; if ( k ) memmove(buff,buff+k,strlen(buff)+1-k); else buff++; } } static int char_is_space(int c) { if ( c==32 || c==13 || c==10 || c==9 ) return(1); else return(0); } static char **tokenize_spaces_dyn(char *buff) { int intoken,inquota,i,n,nm; char **rtokens; nm=16; rtokens=(char **)malloc(sizeof(char *)*nm); malloc_check(rtokens); if ( rtokens==NULL ) return(NULL); intoken=0,inquota=0;n=0; while ( *buff ) { if ( ( ! char_is_space(*buff) ) && ! intoken ) { rtokens[n]=buff; intoken=!0,inquota=0;n++; if ( *buff=='"' ) inquota=!0; buff++; if ( n>=nm-1 ) { nm+=16; rtokens=(char **)realloc(rtokens,sizeof(char *)*nm); realloc_check(rtokens,sizeof(char *)*nm); } } else if ( intoken && ( (char_is_space(*buff) && inquota) || (!char_is_space(*buff)) ) ) { if ( *buff=='"' ) inquota=!inquota; buff++; } else if ( intoken && ! inquota && char_is_space(*buff) ) { *buff=0,buff++; intoken=0; } else buff++; }; rtokens[n]=NULL; for ( i=0 ; i0 ) l++; if ( l>width-p ) { fprintf(fw,"\n"); for ( i=0 ; i0 ) l--; w=0; p=fpad; } if ( w>0 ) fprintf(fw," %s",cmd[n]); else fprintf(fw,"%s",cmd[n]); p+=l; w++; }; fprintf(fw,"\n"); if ( cmd != NULL ) free(cmd); free(dd); } return(0); } int longhelp_fprint_entry(FILE *fw,longhelp_entry *entry,int flags,int width) { int w,fpad,pad; w=fprintf(fw," %s",entry->options); pad=(w+4+7)&(~7); fpad=16; if ( width>0 ) longhelp_fprint_description(fw,width,w,fpad,pad,entry->description); else { for ( ; wdescription); } return(0); } int longhelp_fprint(FILE *fw,longhelp_entry *entry,int flags,int width) { int lcnt; if ( width<0 && isatty(fileno(fw)) ) { #ifdef TIOCGWINSZ struct winsize ws; if ( ! ioctl(fileno(fw),TIOCGWINSZ,&ws) ) width=ws.ws_col-1; else #endif width=0; } lcnt=0; while ( entry != NULL && entry->options != NULL ) { if ( entry->description == NULL ) { if ( lcnt>0 ) { fprintf(fw,"\n"); } fprintf(fw,"%s\n", entry->options); lcnt=0; } else { longhelp_fprint_entry(fw,entry,flags,width); lcnt++; } entry++; } return(0); } static char *longhelp_valid_html(char *in) { char *out; int len,alen; len=0; alen=256; out=malloc(alen); while ( *in ) { if ( alen <= len+16 ) { alen+=256; out=realloc(out,alen); } if ( *in=='<' ) { memcpy(out+len,"<",4);len+=4; } else if ( *in=='>' ) { memcpy(out+len,">",4);len+=4; } else { out[len]=*in,len++; } in++; } out[len]=0; return(out); } static int longhelp_fprint_mediawiki_string(FILE *fw,char *string) { char *line,**cmd; int i; line=longhelp_valid_html(string); cmd=tokenize_spaces_dyn(line); for ( i=0 ; cmd[i] != NULL ; i++ ) { if ( cmd[i][0]=='-' ) fprintf(fw,"'''%s''' ",cmd[i]); else fprintf(fw,"%s ",cmd[i]); } free(cmd); free(line); return(0); } int longhelp_fprint_mediawiki(FILE *fw,longhelp_entry *entry) { while ( entry != NULL && entry->options != NULL ) { if ( entry->description == NULL ) { if ( (entry+1)->options != NULL && strcmp((entry+1)->options,"")==0 && (entry+1)->description==NULL ) fprintf(fw,": %s\n",entry->options); else if ( strcmp(entry->options,"") != 0 ) fprintf(fw,"=== %s ===\n",entry->options); fprintf(fw,"\n"); } else { fprintf(fw,": "); longhelp_fprint_mediawiki_string(fw,entry->options); fprintf(fw,"\n"); fprintf(fw,":: "); longhelp_fprint_mediawiki_string(fw,entry->description); fprintf(fw,"\n"); fprintf(fw,"\n"); } entry++; } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/fiinfo.c0000644000175000017500000010067412771247650013503 0ustar apalapal/*****************************************************************************/ /* fiinfo.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line user interface to get some statistics from FITS data. */ /*****************************************************************************/ #define FITSH_FIINFO_VERSION "0.9d2" /*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "fitsmask.h" #include "math/spline/biquad.h" #include "math/spline/spline.h" #include "math/fit/lmfit.h" #include "statistics.h" #include "math/poly.h" #include "math/polyfit.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "link/linkpoint.h" #include "tensor.h" #include "common.h" #include "fiinfo.h" /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int fprint_fiinfo_usage(FILE *fw) { fprintf(fw, "Usage:\tfiinfo [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[[] [--ignore-mask]] [--frame ]]\n" "\t[-o|--output ] [--[long-]summary]\n"); fprintf(fw, "\t[-s|--statistics [mean|median],[iterations=],[lower|upper|sigma=]]\n" "\t[-d min,max,mean,stddev,sky,skysigma,bgdump,bgfit,bgsky,bgskysigma] [-n]\n" "\t[-b|--box ] [-a|--order ]\n" "\t[--output-dump [-m|--dump--mask]]\n"); fprintf(fw, "Generating PGM/PPM images:\n" "\t[--output-pnm ]\n" "\t[--pgm|--ppm {[defaults],[reverse],[contrast=],[brightness=]\n" "\t [palette=],[linear|log|squared|sqrt|histequ],\n" "\t [8|8bit|16|16bit],[minmax|percentage=<%%>|min=,max=|\n" "\t zscale|zmax|zmin,[zcontrast=]]}]]\n"); return(0); } longhelp_entry fiinfo_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-i, --input ", "Name of the input FITS image file." }, { "--summary, --long-summary", "Give a summary about the content structure of the FITS file. Namely, " "the main characteristics and dimensions of the primary image, followed " "by the list of optional extensions and their main properties." }, { "-s, --statistics ", "Calculate basic statistics for the image. See \"Statistics options\" " "below for available statistics methods. The statistics itself " "contains four numbers: the total number of pixels involved in the " "calculations, the final number of pixels used for the statistics " "(which might be smaller than the previous one if the outliers are " "rejected), an average value and a scatter." }, { "-d, --data ", "Calculate some other more quantities related to astronomical images. " "This option should be followed by a comma-separated list of quantities. " "See \"Image characteristics\" below for more details about these." }, { "-b, --box ", "This option specifies the number of blocks, which is used to divide " "the input image. Some quantities (see \"Image characteristics\") " "can be derived on a per block basis either." }, { "-a, --order ", "Order of polynomial spatial variations in some derived image " "characterization quantities (see also \"Image characteristics\")." }, { "-n, --newline", "In the output, each quantity should be written in separate lines. " "By default, the output is a single line, containing the desired " "quantities or statistics." }, { "--ignore-mask", "Completely ignore the mask associated to the input image." }, { "--output-dump ", "Name of an output file in which a raw image dump is written. " "Each line of this file contains 3 or 4 columns: X, Y coordinates " "and flux, optionally followed by the associated mask flag " "(see also \"-m|--dump-mask\")." }, { "-m, --dump-mask", "The raw image dump specified by \"--output-dump\" should contain " "the masking information beyond the coordinates and intensities." }, { "--output-pnm, --output-ppm, --output-pgm", "Name of an output file in which the image is stored in a variant of " "PNM format. These images are intended to be a kind of \"human " "visible\" images, appropriately scaled for normal displays. " "These images are stored in PNM format, which is an easily parseable " "(thus raw, uncompressed) format, supported by many graphic programs " "(and by the NETPBM package). Such an image conversation always " "results data loss. " "See also options \"--pgm\" or \"--ppm\" for further details." }, { "--pgm ", "This command line argument is followed by a comma-separated list " "of options, which specifies the scaling and other properties of the " "output image. The resulted image will be a grey-scale (PGM) image, " "even if a color palette is requested. See \"PNM specifications\" below." }, { "--ppm ", "This command line argument is followed by a comma-separated list " "of options, which specifies the scaling and other properties of the " "output image. The resulted image will be a true-color (PPM) image, " "even if a greyscale colormap is requested. See also " "\"PNM specifications\" below for more details." }, { "Statistics options: ", NULL }, { "mean", "The mean value of the pixel intensities." }, { "median", "The median value of the pixel intensities." }, { "iterations", "Reject the outlier pixels before doing any statistics." }, { "lower=, upper=, sigma=", "Lower, upper or common rejection level, in the units of " "standard deviation (which is derived around the mean or median value, " "depending on the request of the user)." }, { "Image characteristics:" ,NULL }, { "min, max", "Minimal and maximal pixel intensities on the image." }, { "mean", "Mean intensity level." }, { "stddev", "Standard deviation." }, { "sky", "Sky background level." }, { "skysigma", "Sky background scatter." }, { "PNM specifications:", NULL }, { "linear", "Use a linear intensity scaling." }, { "log", "Use a logarithmic intensity scaling." }, { "squared", "Use a squared intensity scaling." }, { "sqrt", "Use a square root intensity scaling." }, { "histequ", "Use a histogram equalized intensity scaling." }, { "minmax", "Use the minimal and maximal pixel intensities for scaling boundaries." }, { "percentage=<%>", "Use the minimal and maximal values of the innermost " "specified percent of the pixel intensities." }, { "min=, max=", "Use the specified minimal and maximal values for scaling boundaries." }, { "zscale", "Use the \"zscale\" algorithm to determine scaling boundaries." }, { "zmax, zmin", "Use the \"zmax\" or \"zmin\" algorithm to determine scaling boundaries." }, { "zcontrast=", "Use the specified contrast value to determine the scaling boundaries " "in the case of \"zscale\", \"zmax\" or \"zmin\" methods. The default " "value is 0.25." }, { "reverse", "Use an inverted color map." }, { "contrast=, brightness=", "Use the specified values for adjusting the final contrast and " "brightness. The default values are 1 and 0.5, respectively, " "according to the standard image contrast and " "brightness level definitions." }, { "8, 8bit" , "Create an 8-bit PGM or PPM output. This is the default." }, { "16, 16bit" , "Create a 16-bit PGM or PPM output instead of the default 8-bit." }, { "palette=:::...", "Specify an alternate color map. Each color should be a hexadecimal " "representation of a given color, i.e. it should be in one of the " "forms of G, GG, GGGG, RGB, RRGGBB or RRRRGGGGBBBB, denoting 4 bit grey, 8 bit grey, 16 bit grey, " "3x4 bit truecolor, 3x8 bit truecolor or 3x16 bit truecolor representation, respectively. " "The color map gradient will be continuous if the colors are separated by " "colons. Jumps in the gradient can be defined by separating the " "successive colors by a slash, \"/\" instead of colons." }, { "Note that the syntax followed by the \"--pgm\" or \"--ppm\" command line " "arguments is exactly the same for both options. However, color images " "will be converted to greyscale if \"--pgm\" is specified, and vice versa, " "\"--ppm\" always yields a PPM format, even if the color gradient is " "merely a grayscale one. The default palette is 0:F for both PGM " "and PPM formats, i.e. a pure black - white gradient. ", NULL }, { "", NULL }, { NULL,NULL } }; int fprint_fiinfo_long_help(FILE *fw,int is_wiki) { char *synopsis= "fiinfo [options] [-i ] "; char *description= "The main purpose of the `fiinfo` program is to give some information about " "the FITS files (primarily FITS images, but output dump is supported for " "tables and binary tables also)."; fprint_generic_long_help(fw,is_wiki,fiinfo_long_help,synopsis,description); return(0); } /* void fprint_help(FILE *fw) { fprintf(fw, ": name of input file (optional; by default, data read from stdin).\n" ": name of output file (optional; by default, data written to stdout).\n" "-h|--help: prints info about the usage of the program.\n" "-n : prints a newline character after each data (except 'bdump').\n" "-d <...> : list of statistics to be calculated (and written to the output):\n"); fprintf(fw, " * min, max, mean, stddev: the minimal, maximal and the mean values of the\n" " pixels in the image, and the standard deviaton of the pixels;\n" " * sky, skysigma: naive approximation for the background and the scatter of\n" " the background (reliable only for sparse fields);\n"); fprintf(fw, " * bdump, bfit, bsky, bskysigma: divides the image into\n" " B times B blocks (B can be defined with -b|--box, default value is 16),\n" " estimates the desired parameters for each block and averages them.\n" " The 'bgfit' method fits a polynomial to the sky values (up to the order\n" " defined by -a|--order), the 'bgdump' method dumps the estimated sky\n" " and skysigma values for each block.\n"); } */ /*****************************************************************************/ int format_check(char *f) { while ( *f=='-' || *f=='+' ) f++; while ( isdigit((int)*f) ) f++; if ( *f=='+' ) f++; if ( *f=='.' ) f++; if ( *f=='+' ) f++; while ( isdigit((int)*f) ) f++; if ( *f=='e' || *f=='E' || *f=='f' || *f=='F' || *f=='g' || *f=='G' ) return(0); else return(1); } /*****************************************************************************/ int strmask(char *mbuff,int k) { strcpy(mbuff,"--------"); if ( k & MASK_FAULT ) mbuff[0]='f'; if ( k & MASK_HOT ) mbuff[1]='h'; if ( k & MASK_COSMIC ) mbuff[2]='c'; if ( k & MASK_OUTER ) mbuff[3]='o'; if ( k & MASK_OVERSATURATED ) mbuff[4]='s'; if ( k & MASK_LEAKED ) mbuff[5]='l'; if ( k & MASK_SATURATED ) mbuff[6]='S'; if ( k & MASK_INTERPOLATED ) mbuff[7]='i'; return(0); } #define DAT_MIN 0 #define DAT_MAX 1 #define DAT_MEAN 2 #define DAT_STDDEV 3 #define DAT_MEDIAN 11 #define DAT_SKY 4 #define DAT_SKYSIGMA 5 #define DAT_BGDUMP 6 #define DAT_BGFIT 8 #define DAT_BGSKY 9 #define DAT_BGSKYSIGMA 10 typedef struct { char *name; int code; } dataname; static dataname datanamelist[]= { { "min", DAT_MIN }, { "max", DAT_MAX }, { "mean", DAT_MEAN }, { "stddev", DAT_STDDEV }, { "median", DAT_MEDIAN }, { "sky", DAT_SKY }, { "skysigma", DAT_SKYSIGMA }, { "bgdump", DAT_BGDUMP }, { "bgfit", DAT_BGFIT }, { "bgsky", DAT_BGSKY }, { "bgskysigma", DAT_BGSKYSIGMA }, { NULL, -1 } }; int parse_dump_data(char *dumpstr,int **rdats,int *rndat) { int *dats; int ndat,l,j; char buff[16]; dataname *dnames,*wdd; dats=NULL; ndat=0; dnames=datanamelist; while ( *dumpstr ) { l=0; while ( *dumpstr && *dumpstr != ',' && l<15 ) { buff[l]=*dumpstr, l++,dumpstr++; }; buff[l]=0; if ( *dumpstr==',' ) dumpstr++; for ( wdd=dnames,j=-1 ; wdd->name != NULL && j<0 ; wdd++ ) { if ( strcmp(buff,wdd->name)==0 ) j=wdd->code; } if ( j<0 ) { if ( dats != NULL ) free(dats); return(1); } dats=(int *)realloc(dats,sizeof(int)*(ndat+1)); dats[ndat]=j; ndat++; }; if ( rdats != NULL ) *rdats=dats; if ( rndat != NULL ) *rndat=ndat; return(0); } /*****************************************************************************/ typedef struct { int *dats; int ndat; int nbox,norder; } infoimage; int fits_stat_v1_image(fitsimage *fi,char **mask,FILE *fw,int nwl,infoimage *ii) { int i,j; int is_med,is_mord,is_bg,is_bgdump; double min,max,mean,stddev,sky,skysigma,*pfit,med; double bgsky,bgskysigma; is_med=is_mord=is_bg=is_bgdump=0; for ( i=0 ; indat && ii->dats != NULL ; i++ ) { j=ii->dats[i]; if ( j==11 ) is_med=1; else if ( j==4 || j==5 ) is_mord=1; else if ( j==6 ) is_bg=is_bgdump=1; else if ( j==8 || j==9 || j==10 ) is_bg=1; } /* Basic statistics: min, max, mean and standard deviation: */ fits_stat_basic(fi,mask,&min,&max,&mean,&stddev); /* Statistics which require the pixel data to be ordereded (eg. median): */ if ( is_mord ) fits_stat_sky_biquad(fi,stddev,&sky,&skysigma); if ( is_med ) med=fits_stat_median(fi); else med=0.0; /* Statistics which require the image to be divided into boxes: */ if ( is_bg ) { point **pdsky,**pdsigma; double *rawdata; int i,j,k,nbx,nby; nbx=nby=ii->nbox; pdsky =(point **)tensor_alloc_2d(point,nbx,nby); pdsigma=(point **)tensor_alloc_2d(point,nbx,nby); fits_stat_background(fi,nbx,nby,pdsky,pdsigma,stddev); if ( is_bgdump ) { for ( i=0 ; inorder+1)*(ii->norder+2)/2)); fit_2d_poly(&pdsky[0][0],nbx*nby,ii->norder,pfit,0.5,0.5,1.0); rawdata=(double *)malloc(sizeof(double)*(nbx*nby)); for ( i=0,k=0 ; indat ; i++ ) { switch ( ii->dats[i] ) { case DAT_MIN: fprintf(fw,"%11g ",min); break; case DAT_MAX: fprintf(fw,"%11g ",max); break; case DAT_MEAN: fprintf(fw,"%11g ",mean); break; case DAT_STDDEV: fprintf(fw,"%11g ",stddev); break; case DAT_SKY: fprintf(fw,"%11g ",sky); break; case DAT_SKYSIGMA: fprintf(fw,"%11g ",skysigma); break; case DAT_BGFIT: for ( j=0 ; j<(ii->norder+1)*(ii->norder+2)/2 ; j++ ) { fprintf(fw,"%11g ",pfit[j]); } break; case DAT_BGSKY: fprintf(fw,"%11g ",bgsky); break; case DAT_BGSKYSIGMA: fprintf(fw,"%11g ",bgskysigma); break; case DAT_MEDIAN: fprintf(fw,"%11g ",med); break; } if ( nwl ) fprintf(fw,"\n"); } if ( ! nwl && ii->ndat>0 ) fprintf(fw,"\n"); return(0); } /*****************************************************************************/ typedef struct { double floydratio; int use_median; int niter; double lower,upper; } imgstatparam; static int data_add_point(double **rdata,int *rn,double d) { double *data; int n; data=*rdata; n=*rn; if ( ! (n%256) ) data=(double *)realloc(data,sizeof(double)*(n+256)); data[n]=d; n++; *rdata=data; *rn=n; return(0); } int fits_stat_v2_image(fitsimage *img,char **inmask,FILE *fw,imgstatparam *isp,int is_comment) { int sx,sy; char **mask; int i,j; double *data,center,s2,d,sig,d0,d1,sum; int n,iiter,i0,i1,k; sx=img->sx; sy=img->sy; if ( isp->floydratio>0.0 && isp->floydratio<1.0 ) { int a,b; a=isp->floydratio*32768.0; b=32768; mask=fits_mask_create_floyd(sx,sy,a,b,1); if ( inmask != NULL ) { for ( i=0 ; idata[i][j]); sum+=img->data[i][j]; } } if ( isp->use_median ) center=median(data,n); else { center=sum/(double)n; median(data,n); } i0=0; i1=n; sig=0.0; for ( iiter=0 ; iiter <= (isp->niter>0?isp->niter:0) ; iiter++ ) { s2=0.0; for ( i=i0 ; initer ) { k=0; d0=center-sig*isp->lower; while ( i0upper; while ( 0use_median ) center=0.5*(data[(i1+i0)/2]+data[(i1+i0-1)/2]); else center=sum/(double)(i1-i0); if ( k <= 0 ) break; } } if ( is_comment ) fprintf(fw,"# Num used average scatter \n"); fprintf(fw," %8d %8d %12.7g %12.7g\n",n,i1-i0,center,sig); if ( mask != NULL && mask != inmask ) fits_mask_free(mask); return(0); } /*****************************************************************************/ int fitsttable_dump(FILE *fw,fitsttable *ft) { unsigned char *line; int i,j,p,len; char *buff; if ( fw==NULL ) return(1); if ( ft==NULL || ft->data==NULL || ft->tfields==NULL ) return(1); buff=(char *)malloc(ft->rowsize+1); if ( buff==NULL ) return(-1); for ( i=0 ; inrow ; i++ ) { line=ft->data[i]; for ( j=0 ; jntfield ; j++ ) { p=ft->tfields[j].colindex; if ( jntfield-1 ) len=ft->tfields[j+1].colindex-p; else len=ft->rowsize-p; strncpy(buff,(char *)line+p,len); buff[len]=0; if ( j ) fprintf(fw," %s",buff); else fprintf(fw,"%s",buff); } fprintf(fw,"\n"); } free(buff); return(0); } int fitsbtable_dump(FILE *fw,fitsbtable *fb) { unsigned char *line,*ptr,m; int i,j,k,offset,repeat,basesize,form; char *buff; if ( fw==NULL ) return(1); if ( fb==NULL || fb->data==NULL || fb->bfields==NULL ) return(1); buff=(char *)malloc(fb->rowsize+1); if ( buff==NULL ) return(-1); for ( i=0 ; inrow ; i++ ) { line=fb->data[i]; offset=0; for ( j=0 ; jnbfield ; j++ ) { repeat=fb->bfields[j].repeat; form=fb->bfields[j].form; basesize=fits_bintable_form_basesize(form); if ( basesize<0 ) break; /* unexpected TFORM... */ else if ( basesize>0 && form != FTF_STRING ) { for ( k=0 ; k0 ) { memcpy(buff,line+offset,repeat); buff[repeat]=0; for ( k=0 ; k>(k%8); if ( line[offset+(k/8)] & m ) fprintf(fw,"1"); else fprintf(fw,"0"); } offset+=(repeat+7)/8; } } fprintf(fw,"\n"); } free(buff); return(0); } /*****************************************************************************/ int fprint_fitsimage_summary(FILE *fw,fitsimage *fi) { int i; fprintf(fw,"array:dim=%d:",fi->dim); for ( i=0 ; idim ; i++ ) { if ( i>0 ) fprintf(fw,"x"); fprintf(fw,"%d",fi->naxis[i]); } fprintf(fw," bitpix=%d (%s)\n",fi->bit,fits_image_bitpix_cname(fi->bit)); return(0); } static int cut_spaces(char *in,char *out) { while ( isspace((int)*in) ) in++; while ( *in && ! isspace((int)*in) ) *out=*in,out++,in++; *out=0; return(0); } int fprint_fitsttable_summary(FILE *fw,fitsttable *ft,int nwl) { int i; char buff[32],*format,*p; fprintf(fw,"rows=%d rowsize=%d ",ft->nrow,ft->rowsize); fprintf(fw,"fields:"); for ( i=0 ; intfield ; i++ ) { if ( i>0 ) fprintf(fw,","); format=ft->tfields[i].format; while ( *format && isspace((int)*format) ) format++; strncpy(buff,format,31);buff[31]=0; p=strchr(buff,32); if ( p != NULL ) *p=0; fprintf(fw,"%s",buff); } fprintf(fw,"\n"); return(0); } int fprint_fitsbtable_summary(FILE *fw,fitsbtable *fb,int nwl) { int i; char type[32],unit[32],null[32],*cname; fprintf(fw,"rows=%d rowsize=%d ",fb->nrow,fb->rowsize); if ( ! nwl ) { fprintf(fw,"fields:"); for ( i=0 ; inbfield ; i++ ) { if ( i>0 ) fprintf(fw,","); fprintf(fw,"%dx%c",fb->bfields[i].repeat,fb->bfields[i].form); } fprintf(fw,"\n"); } else { fprintf(fw,"nfield=%d\n",fb->nbfield); for ( i=0 ; inbfield ; i++ ) { fprintf(fw,"\t\t\t\t%2dx",fb->bfields[i].repeat); cname=fits_bintable_form_cname(fb->bfields[i].form); cut_spaces(fb->bfields[i].type,type); cut_spaces(fb->bfields[i].unit,unit); cut_spaces(fb->bfields[i].null,null); fprintf(fw," (%s)",cname); if ( type[0] ) { fprintf(fw,"%s",type); } else { fprintf(fw,"'%c'",fb->bfields[i].form); } if ( unit[0] ) { fprintf(fw,"\t[%s]",unit); } fprintf(fw,"\n"); } } return(0); } int fprint_fits_summary(FILE *fw,fits *img,int nwl) { int is_primary,i,fcnt; if ( img->i.vdata != NULL ) is_primary=1; else is_primary=0; if ( ! is_primary ) { fprintf(fw,"Primary : NONE\n"); fcnt=0; } else { fprintf(fw,"Primary [1]: IMAGE : "); fprint_fitsimage_summary(fw,&img->i); fcnt=1; } for ( i=0 ; inxtn ; i++ ) { fitsheader *fh; fh=fits_headerset_get_header(&img->xtns[i].header,"EXTNAME",0); if ( fh != NULL && fh->vtype==FITS_VSTR ) fprintf(fw,"Extension ['%s']: ",fh->vstr); else fprintf(fw,"Extension [%d]: ",fcnt+1); switch ( img->xtns[i].type ) { case FITS_EXT_IMAGE: fprintf(fw,"IMAGE : "); fprint_fitsimage_summary(fw,&img->xtns[i].x.i); break; case FITS_EXT_TABLE: fprintf(fw,"TABLE : "); fprint_fitsttable_summary(fw,&img->xtns[i].x.t,nwl); break; case FITS_EXT_BINTABLE: fprintf(fw,"BINTABLE: "); fprint_fitsbtable_summary(fw,&img->xtns[i].x.b,nwl); break; default: fprintf(fw,"UNKNOWN\n"); break; } fcnt++; } return(0); } int main(int argc,char *argv[]) { fits *img; FILE *fw,*fr; int i,j,sx,sy,is_help,frameno,is_primary,is_summary; char *file_in,*file_out,*file_inbase, *file_outpnm,*file_outdump, *statstr,*dumpstr,*dumpformat,*pnmmstr,*file_outbg; int ignore_mask,is_ppm,dump_mask; int nwl; char **mask; pnmparam pp; infoimage ii; imgstatparam isp; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; is_help=is_verbose=is_comment=0; file_outbg=file_outpnm=file_in=file_out=file_outdump=NULL; statstr=NULL; ii.nbox=16,ii.norder=2; ii.dats=NULL,ii.ndat=0; dumpstr=NULL;nwl=0; pnmmstr=NULL;ignore_mask=0;frameno=-1,is_summary=0; dump_mask=0; dumpformat="%12g"; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-i|--input:%s",&file_in, "--frame:%d",&frameno, "--summary:%f",&is_summary, "--long-summary:%f%f",&is_summary,&nwl, "-o|--output:%s",&file_out, /* I */ "--output-dump:%s",&file_outdump, "-F|--format:%s",&dumpformat, /* I */ "--output-background:%s",&file_outbg, "-m|--dump-mask:%f",&dump_mask, /* I */ "--output-pnm|--output-ppm|--output-pgm:%s",&file_outpnm, "--pgm:%SN0f%s",&is_ppm,&pnmmstr, "--ppm:%SN1f%s",&is_ppm,&pnmmstr, "-n|--newline|-l|--long:%f",&nwl, "--ignore-mask:%f",&ignore_mask, "-b|--box:%d",&ii.nbox, "-a|--order:%d",&ii.norder, /* I */ "-d|--data:%s",&dumpstr, "-s|--statistics:%s",&statstr, "--comment:%i",&is_comment,"(C):%i",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-:%w",&file_in, "-*|+*:%e", "*:%w",&file_in, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fiinfo",FITSH_FIINFO_VERSION,is_help); return(0); } else if ( 1=30 ) { fprint_error("unexpected format token '%s'.\n",dumpformat); return(1); } if ( dumpstr != NULL ) { i=parse_dump_data(dumpstr,&ii.dats,&ii.ndat); if ( i ) { fprint_error("invalid data format '%s'",dumpstr); return(1); } } if ( statstr != NULL ) { double sigma; isp.floydratio=0.0; isp.niter=0; isp.lower=3.0; isp.upper=3.0; isp.use_median=0; sigma=0.0; i=scanpar(statstr,SCANPAR_DEFAULT, "ratio:%g",&isp.floydratio, "iterations:%d",&isp.niter, "sigma:%g",&sigma, "lower:%g",&isp.lower, "upper:%g",&isp.upper, "median:%SN1f",&isp.use_median, "mean:%SN0f",&isp.use_median, NULL); if ( i ) { fprint_error("invalid statistical parameter in '%s'.\n",statstr); return(1); } if ( sigma>0.0 ) { isp.lower=sigma; isp.upper=sigma; } } pp.is_invert=0;pp.minmaxmethod=0,pp.scalemethod=0; pp.mmin_set=pp.mmax_set=0; pp.zcontrast=0.25; pp.percentage=90.0; pp.contrast=1.0; pp.brightness=0.5; pp.palette=NULL;pp.ncol=0; pp.is_color=is_ppm; pp.is_16bit=0; pp.is_flip=pp.is_mirror=0; if ( pnmmstr != NULL ) { char *palstr; int dummy; palstr=NULL; dummy=0; j=scanpar(pnmmstr,SCANPAR_DEFAULT, "default|defaults:%f",&dummy, "linear:" SNf(SCALE_LINEAR) ,&pp.scalemethod, "histequ:" SNf(SCALE_HISTEQU),&pp.scalemethod, "log:" SNf(SCALE_LOG) ,&pp.scalemethod, "sqrt:" SNf(SCALE_SQRT) ,&pp.scalemethod, "squared:" SNf(SCALE_SQUARED),&pp.scalemethod, "minmax:" SNf(MM_MINMAX) ,&pp.minmaxmethod, "zscale:" SNf(MM_ZSCALE) ,&pp.minmaxmethod, "zmin:" SNf(MM_ZMIN) ,&pp.minmaxmethod, "zmax:" SNf(MM_ZMAX) ,&pp.minmaxmethod, "percentage:" SNf(MM_PERCENTAGE)"%g",&pp.minmaxmethod,&pp.percentage, "min:" SNf(MM_MANUAL)"%f%g",&pp.minmaxmethod,&pp.mmin_set,&pp.manmin, "max:" SNf(MM_MANUAL)"%f%g",&pp.minmaxmethod,&pp.mmax_set,&pp.manmax, "8|8bit:" SNf(0),&pp.is_16bit, "16|16bit:%f", &pp.is_16bit, "flip:%f",&pp.is_flip, "flop|mirror:%f",&pp.is_mirror, "palette:%s",&palstr, "zcontrast:%g",&pp.zcontrast, "reverse:%f",&pp.is_invert, "contrast:%g",&pp.contrast, "brightness:%g",&pp.brightness, NULL); if ( j ) { fprint_error("invalid PNM specifications in '%s'",pnmmstr); return(1); } if ( pp.percentage<0 ) pp.percentage=1.0; else if ( pp.percentage>100.0 ) pp.percentage=100.0; if ( pp.contrast<0.0 ) pp.contrast =0.0; if ( pp.brightness<0.0 ) pp.brightness=0.0; else if ( pp.brightness>1.0 ) pp.brightness=1.0; if ( palstr != NULL && parse_palette(palstr,&pp.palette,&pp.ncol) ) { fprint_error("invalid palette format"); } } /* Read input image from stdin or 'file_in': */ file_inbase=fits_basename(file_in,&frameno); fr=fopenread(file_inbase); if ( fr==NULL ) { fprint_error("unable to open input file '%s'.",file_inbase); return(1); } if ( frameno<0 || is_summary ) img=fits_read(fr); else img=fits_read_frame_as_extension(fr,frameno); fcloseread(fr); if ( img==NULL ) { fprint_error("unable to read input file as FITS data."); return(1); } if ( img->i.vdata != NULL ) is_primary=1; else is_primary=0; if ( is_summary ) { fprint_fits_summary(stdout,img,nwl); return(0); } else if ( img->nxtn>=2 || (img->nxtn>=1 && is_primary) ) { fprintf(stderr,"Warning: FITS data contains multiple arrays or extensions, summary reported.\n"); fprint_fits_summary(stdout,img,nwl); return(0); } else if ( is_primary || (img->xtns != NULL && img->xtns[0].type==FITS_EXT_IMAGE ) ) { fitsimage *fi; if ( is_primary ) { fi=&img->i; fits_image_get_params(&img->header,fi); } else { fi=&img->xtns[0].x.i; fits_image_get_params(&img->xtns[0].header,fi); } fits_image_rescale(fi); if ( ignore_mask ) mask=NULL; else if ( is_primary ) { mask=fits_mask_read_from_header(&img->header,fi->sx,fi->sy,NULL); fits_mask_mark_nans(fi,mask,MASK_NAN); } else { mask=fits_mask_read_from_header(&img->xtns[0].header,fi->sx,fi->sy,NULL); fits_mask_mark_nans(fi,mask,MASK_NAN); } if ( file_out==NULL ) fw=stdout; else fw=fopenwrite(file_out); if ( fw==NULL ) { fprint_error("unable to create output file '%s'",file_out); return(1); } if ( ii.ndat>0 ) fits_stat_v1_image(fi,mask,fw,nwl,&ii); else if ( statstr != NULL ) fits_stat_v2_image(fi,mask,fw,&isp,is_comment); sx=fi->sx, sy=fi->sy; if ( file_outdump==NULL && dump_mask ) { int maskcount[128]; int i,j,k; char mbuff[16]; for ( k=0 ; k<128 ; k++ ) { maskcount[k]=0; } if ( mask==NULL ) maskcount[0]=sx*sy; else { for ( i=0 ; idata[i][j]); if ( dump_mask ) { if ( mask != NULL ) k=mask[i][j]; else k=0; strmask(mbuff,k); fprintf(fw," %s\n",mbuff); } else fprintf(fw,"\n"); } } fclosewrite(fw); } if ( file_outpnm != NULL ) { fw=fopenwrite(file_outpnm); if ( fw==NULL ) { fprint_error("unable to create output PNM image file '%s'",file_outpnm); return(1); } fits_image_rescale(fi); fitsimage_dump_pnm(fi,mask,fw,&pp); fclosewrite(fw); } if ( file_outbg != NULL ) { fits *bgimg; bgimg=fits_duplicate(img); create_link_background(fi,mask,&bgimg->i,0,0); fw=fopenwrite(file_outbg); if ( fw==NULL ) { fprint_error("unable to create output background file '%s'",file_outbg); return(1); } fits_write(fw,bgimg); fclosewrite(fw); fits_free(bgimg); } /* Release the mask 'mask': */ if ( mask != NULL ) fits_mask_free(mask); } else if ( img->xtns != NULL && img->xtns[0].type==FITS_EXT_TABLE ) { if ( file_out != NULL ) fw=fopenwrite(file_out); else fw=stdout; if ( fw==NULL ) { fprint_error("unable to create output file '%s'",file_out); return(1); } fitsttable_dump(fw,&img->xtns[0].x.t); fclosewrite(fw); } else if ( img->xtns != NULL && img->xtns[0].type==FITS_EXT_BINTABLE ) { if ( file_out != NULL ) fw=fopenwrite(file_out); else fw=stdout; if ( fw==NULL ) { fprint_error("unable to create output file '%s'",file_out); return(1); } fitsbtable_dump(fw,&img->xtns[0].x.b); fclosewrite(fw); } /* Release the FITS data 'img': */ fits_free(img); return(0); } fitsh-0.9.2/src/kernel-base.c0000644000175000017500000004046712771247652014426 0ustar apalapal/*****************************************************************************/ /* kernel-base.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Base functions for manipulating convolution kernels. */ /*****************************************************************************/ #include #include #include #include #include #include #include "fitsh.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "io/tokenize.h" #include "io/iof.h" #include "tensor.h" #include "kernel.h" int kernel_verbose=2; #define KERNEL_LOG 1 /*****************************************************************************/ int kernel_set_verbosity(int vlevel) { if ( vlevel>0 ) kernel_verbose=vlevel; else kernel_verbose=0; return(0); } /*****************************************************************************/ /* hermite(): Evaluates H_n(x). (Currently, it's obsolente...) */ double hermite(int n,double x) { double hp,hpp,h; int k; switch ( n ) { case 0 : return(1.0); case 1 : return(2.0*x); case 2 : return(4.0*x*x-2.0); case 3 : return(x*(8.0*x*x-12.0)); default : if ( n<0 ) return(0.0); h=hp=2.0*x,hpp=1.0; for ( k=1 ; k0 ) { if ( n&1 ) w=w*t; t=t*t,n=n/2; }; return(w); } /* eval_gaussian(): Evaluates exp(-1/2*(u*u+v*v)/(...))*u^(...)*v^(...), depending on the parameters (sigma, basis bx and by) of the Gaussian kernel 'k'. */ double eval_gaussian(kernel *k,double u,double v) { double w; w=exp(-(u*u+v*v)/(2.0*k->sigma*k->sigma))*monom(k->bx,u)*monom(k->by,v); return(w); } /* kernel_image_norm(): Norms kernel image 'k->image' so sum of the kernel pixels will be 'sum'. */ int kernel_image_norm(kernel *k,double sum) { int i,j; double w; if ( k->image==NULL ) return(1); w=0.0; for ( i=0 ; i<=2*k->hsize ; i++ ) { for ( j=0 ; j<=2*k->hsize ; j++ ) { w=w+k->image[i][j]; } } w=sum/w; for ( i=0 ; i<=2*k->hsize ; i++ ) { for ( j=0 ; j<=2*k->hsize ; j++ ) { k->image[i][j]=k->image[i][j]*w; } } return(0); } /* kernel_image_calc_gaussian(): Calculates 'k->image' for a given 'k->hsize' using the parametes of a Gaussian kernel. Uses a grid with a size of 'subg' times 'subg' for the numerical integration on each pixel. */ int kernel_image_calc_gaussian(kernel *k) { int i,j,hsize,bx,by,subg; hsize=k->hsize; bx=k->bx, by=k->by; k->image=matrix_alloc(2*hsize+1); subg=10; for ( i=0 ; i<=2*hsize ; i++ ) { for ( j=0 ; j<=2*hsize ; j++ ) { double w,dx,dy; int m,n; w=0.0; for ( m=0 ; mimage[i][j]=w/(double)(subg*subg); } } if ( bx%2==0 && by%2==0 ) { kernel_image_norm(k,1.0); } k->offset=0.0; return(0); } int kernel_image_calc_linear(kernel *k) { int i,j,mx,px,py; px=k->bx,py=k->by; mx=abs(px); if ( abs(py)>mx ) mx=abs(py); k->hsize=mx; k->image=matrix_alloc(2*mx+1); for ( i=0 ; i<=2*mx ; i++ ) { for ( j=0 ; j<=2*mx ; j++ ) { k->image[i][j]=0.0; } } k->image[mx+ 0][mx+ 0]=-0.5; k->image[mx+py][mx+px]=+0.5; k->offset=0.0; return(0); } int kernel_image_subtract(kernel *k,kernel *subk) { int i,j,hsk,hss,mh; mh=hsk=k->hsize; hss=subk->hsize; if ( hssimage[i+hsk][j+hsk]-=subk->image[i+hss][j+hss]; } } return(0); } /*****************************************************************************/ double convolve_point(fitsimage *img,kernel *k,int x,int y) { int i,j,hsize; double w; w=0.0; if ( k->type==KERNEL_UNKNOWN || k->type==KERNEL_GAUSSIAN ) { hsize=k->hsize; for ( i=-hsize ; i<=hsize ; i++ ) { for ( j=-hsize ; j<=hsize ; j++ ) { w+=img->data[y-i][x-j]*k->image[hsize+i][hsize+j]; } } w+=k->offset; } else if ( k->type==KERNEL_BACKGROUND ) { w=1.0; } else if ( k->type==KERNEL_IDENTITY ) { w=img->data[y][x]; } else if ( k->type==KERNEL_DDELTA ) { int bx,by; bx=k->bx,by=k->by; w=0.5*(img->data[y-by][x-bx]-img->data[y][x]); } else fprintf(stderr,"???\n"); return(w); } int convolve_image(fitsimage *img,char **mask,kernel *k,fitsimage *out) { int i,j,sx,sy; if ( out->sx != img->sx || out->sy != img->sy ) return(1); sx=img->sx,sy=img->sy; for ( i=0 ; idata[i][j]=convolve_point(img,k,j,i); } } return(0); } /*****************************************************************************/ typedef struct _stamp_struct { int x,y; int sx,sy; double xc,yc; } stamp; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int fit_kernel_poly_coefficients_subblock(fitsimage *refimg,fitsimage *img, char **mask,double **weight, stamp *stamps,int nstamp,kernellist *klist,kernellist *xlist) { int b,i,j,k,l,nvar,nkernel,nvp,fkernel; int sx,sy,mxorder; double **amatrix,*bvector; double **nsamatrix,*nsbvector,*nsconv; int *koffset,*foffset; double *monoms; kernel *kernels,*wk; double ox,oy,scale; sx=refimg->sx,sy=refimg->sy; if ( img->sx != sx || img->sy != sy ) return(1); ox=0.5*(double)(sx); oy=0.5*(double)(sy); scale=0.5*(double)sx; for ( i=0 ; inkernel ; i++ ) { klist->kernels[i].target=0; } if ( xlist != NULL ) { for ( i=0 ; xlist->kernels != NULL && inkernel ; i++ ) { kernel *x,*k; int nk; x=&xlist->kernels[i]; if ( x->type == KERNEL_BACKGROUND || x->type == KERNEL_IDENTITY ) continue; nk=klist->nkernel; klist->kernels=(kernel *)realloc(klist->kernels,sizeof(kernel)*(nk+1)); k=&klist->kernels[nk]; memcpy(k,x,sizeof(kernel)); k->target=1; k->flag=1; klist->nkernel++; } } kernels=klist->kernels; nkernel=klist->nkernel; koffset=(int *)malloc(sizeof(int)*nkernel); foffset=(int *)malloc(sizeof(int)*nkernel); nvar=0;mxorder=0;fkernel=0; for ( i=0 ; imxorder ) mxorder=order; if ( kernels[i].flag<=0 ) continue; koffset[i]=nvar; nvar += (order+1)*(order+2)/2; foffset[fkernel]=i; fkernel++; } if ( fkernel==0 ) /* There's nothing to be fitted. */ { free(koffset); free(foffset); return(0); } nvp=(mxorder+1)*(mxorder+2)/2; #if KERNEL_LOG != 0 logmsg(kernel_verbose>=2," -> allocating desired memory " "[nkernel=%d,fkernel=%d,nvar=%d]...",nkernel,fkernel,nvar); #endif amatrix=matrix_alloc(nvar); bvector=vector_alloc(nvar); monoms=vector_alloc(nvp); nsamatrix=matrix_alloc(fkernel); nsbvector=vector_alloc(fkernel); nsconv=vector_alloc(nkernel); #if KERNEL_LOG != 0 logmsg(kernel_verbose>=2,"done.\n"); logmsg(kernel_verbose>=2," -> calculating least-squares matrix..."); #endif for ( i=0 ; i=0 ) { if ( ! kernels[k].target ) nsconv[k]=convolve_point(refimg,&kernels[k],j,i); else nsconv[k]=-convolve_point(img,&kernels[k],j,i); } else nsconv[k]=0.0; } if ( weight != NULL ) w=weight[i][j]; else w=1.0; if ( w<=0.0 ) continue; d=img->data[i][j]; /* The kernels with flag==0 should */ /* be taken into account here... */ for ( k=0,wk=kernels ; kflag != 0 ) continue; kn=(wk->order+1)*(wk->order+2)/2; for ( l=0 ; lcoeff[l]*monoms[l]; } /* Build the LS matrix, using the */ /* elements of the LS-basis nsconv[].*/ for ( k=0 ; k=2,"done.\n"); logmsg(kernel_verbose>=2," -> solving the linear least-squares equation..."); #endif solve_gauss(amatrix,bvector,nvar); #if KERNEL_LOG != 0 logmsg(kernel_verbose>=2,"done.\n"); logmsg(kernel_verbose>=2," -> saving fitted parameters to the kernel description array..."); #endif klist->type=1; klist->ox=ox,klist->oy=oy; klist->scale=scale; for ( i=0 ; iorder; knv=(korder+1)*(korder+2)/2; if ( wk->coeff != NULL ) free(wk->coeff); wk->coeff=(double *)malloc(sizeof(double)*knv); k=koffset[fi]; for ( j=0 ; jcoeff[j]=bvector[k+j]; } } #if KERNEL_LOG != 0 logmsg(kernel_verbose>=2,"done.\n"); #endif matrix_free(nsamatrix); vector_free(nsbvector); vector_free(nsconv); vector_free(monoms); vector_free(bvector); matrix_free(amatrix); free(foffset); free(koffset); if ( xlist != NULL ) { xlist->nkernel=0; for ( i=0 ; itarget ) { memcpy(&xlist->kernels[xlist->nkernel],wk,sizeof(kernel)); xlist->nkernel++; if ( iox=ox,xlist->oy=oy; xlist->scale=scale; xlist->type=1; } klist->kernels=kernels; klist->nkernel=nkernel; return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fit_kernel_poly_coefficients_block(fitsimage *refimg,fitsimage *img, char **mask,double **weight,int nbx,int nby,kernellist *klist,kernellist *xlist) { int bi,bj,b,ret,sx,sy; int nstamp; stamp *stamps; nstamp=nbx*nby; stamps=(stamp *)malloc(sizeof(stamp)*nstamp); sx=img->sx, sy=img->sy; for ( bi=0 ; bisx,sy=refimg->sy; if ( outimg->sx != sx || outimg->sy != sy ) return(1); ox=klist->ox, oy=klist->oy; scale=klist->scale; for ( i=0 ; i=2,"\rPerforming the linear transformation... [%4d/%4d] ",i+1,sy); #endif for ( j=0 ; jdata[i][j]=0.0; continue; } c=0.0; for ( n=0,k=klist->kernels ; nnkernel ; n++,k++ ) { w=eval_2d_poly((double)j,(double)i,k->order,k->coeff,ox,oy,scale); p=convolve_point(refimg,k,j,i); c += w*p; } outimg->data[i][j]=c; } } #if KERNEL_LOG != 0 logmsg(kernel_verbose>=2,"done.\n"); #endif return(0); } int convolve_with_kernel_set(fitsimage *refimg,char **mask,kernellist *klist,fitsimage *outimg) { int r; if ( klist->type ) r=convolve_with_kernel_set_poly(refimg,mask,klist,outimg); else r=-1; return(r); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int convolve_to_subtracted_poly(fitsimage *ref,fitsimage *img,char **mask, kernellist *klist,kernellist *xlist,fitsimage *outimg) { int i,j,sx,sy; double ox,oy,scale; sx=ref->sx,sy=ref->sy; if ( outimg->sx != sx || outimg->sy != sy ) return(1); if ( img->sx != sx || img->sy != sy ) return(1); ox=klist->ox, oy=klist->oy; scale=klist->scale; for ( i=0 ; i=2,"\rPerforming the linear transformation... [%4d/%4d] ",i+1,sy); #endif for ( j=0 ; jdata[i][j]=0.0; continue; } c=img->data[i][j]; if ( xlist != NULL ) { for ( n=0,k=xlist->kernels ; nnkernel ; n++,k++ ) { w=eval_2d_poly((double)j,(double)i,k->order,k->coeff,ox,oy,scale); p=convolve_point(img,k,j,i); c += w*p; } } for ( n=0,k=klist->kernels ; nnkernel ; n++,k++ ) { w=eval_2d_poly((double)j,(double)i,k->order,k->coeff,ox,oy,scale); p=convolve_point(ref,k,j,i); c -= w*p; } outimg->data[i][j]=c; } } #if KERNEL_LOG != 0 logmsg(kernel_verbose>=2,"done.\n"); #endif return(0); } int convolve_to_subtracted(fitsimage *ref,fitsimage *img,char **mask, kernellist *klist,kernellist *xlist,fitsimage *outimg) { int r; if ( klist->type ) r=convolve_to_subtracted_poly(ref,img,mask,klist,xlist,outimg); else r=-1; return(r); } /*****************************************************************************/ fitsh-0.9.2/src/star-base.c0000644000175000017500000002513212771247655014112 0ustar apalapal/*****************************************************************************/ /* star-base.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Base module (common functions) for star searching and fitting... */ /*****************************************************************************/ #include #include #include #include #include "fitsh.h" #include "common.h" #include "stars.h" /*****************************************************************************/ /* fit_small_parabola_point(), fit_small_parabola_block(), Fits the A+B*(dx)+C*(dy)+1/2*D*(dx)^2+E*(dx)*(dy)+1/2*F*(dy)^2 parabola to the nine points / blocks of the image section [x-1:x+1,y-1:y+1] (dx=-1, 0, 1 and dy=-1, 0, 1 for this nine point/block). The fit parameters A, B, C, D, E and F are stored in the array fit: in fit[0], fit[1], fit[2], fit[3], fit[4], and fit[5] respectively. If the point (x,y) is out of the image boundary, a nonzero value is returned indicating the error, otherwise the functions return 0. */ int fit_small_parabola_point(fitsimage *img,int x,int y,double *fit) { double bv[6],xls,xhs,yls,yhs; if ( x<1 || y<1 || x>=img->sx-1 || y>=img->sy-1 ) return(1); xls=img->data[y-1][x-1]+img->data[y ][x-1]+img->data[y+1][x-1]; xhs=img->data[y-1][x+1]+img->data[y ][x+1]+img->data[y+1][x+1]; yls=img->data[y-1][x-1]+img->data[y-1][x ]+img->data[y-1][x+1]; yhs=img->data[y+1][x-1]+img->data[y+1][x ]+img->data[y+1][x+1]; bv[0]=xls+(img->data[y-1][x]+img->data[y][x]+img->data[y+1][x])+xhs; bv[1]=xhs-xls; bv[2]=yhs-yls; bv[3]=0.5*(xhs+xls); bv[4]= (img->data[y-1][x-1]+img->data[y+1][x+1])- (img->data[y+1][x-1]+img->data[y-1][x+1]); bv[5]=0.5*(yhs+yls); fit[0]=(5.0*bv[0]-6.0*(bv[3]+bv[5]))/9.0; fit[1]=bv[1]/6.0; fit[2]=bv[2]/6.0; fit[3]=(-2.0*bv[0]+6.0*bv[3])/3.0; fit[4]=0.25*bv[4]; fit[5]=(-2.0*bv[0]+6.0*bv[5])/3.0; return(0); } int fit_small_parabola_block(fitsimage *img,int x,int y,double *fit) { double bv[6],xls,xms,xhs,yls,yms,yhs; if ( x<1 || y<1 || x>=img->sx-1 || y>=img->sy-1 ) return(1); xls=img->data[y-1][x-1]+img->data[y ][x-1]+img->data[y+1][x-1]; xms=img->data[y-1][x ]+img->data[y ][x ]+img->data[y+1][x ]; xhs=img->data[y-1][x+1]+img->data[y ][x+1]+img->data[y+1][x+1]; yls=img->data[y-1][x-1]+img->data[y-1][x ]+img->data[y-1][x+1]; yms=img->data[y ][x-1]+img->data[y ][x ]+img->data[y ][x+1]; yhs=img->data[y+1][x-1]+img->data[y+1][x ]+img->data[y+1][x+1]; bv[0]=xls+xms+xhs; bv[1]=xhs-xls; bv[2]=yhs-yls; bv[3]=(13.0*xhs+xms+13.0*xls)/24.0; bv[4]= (img->data[y-1][x-1]+img->data[y+1][x+1])- (img->data[y+1][x-1]+img->data[y-1][x+1]); bv[5]=(13.0*yhs+yms+13.0*yls)/24.0; fit[0]=(97.0/144.0)*bv[0]-0.75*(bv[3]+bv[5]); fit[1]=(1.0/6.0)*bv[1]; fit[2]=(1.0/6.0)*bv[2]; fit[3]=-0.75*bv[0]+2*bv[3]; fit[4]= 0.25*bv[4]; fit[5]=-0.75*bv[0]+2*bv[5]; return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fit_small_parabola_block_param(fitsimage *img,int j,int i, double *rcx,double *rcy,double *raxx,double *raxy,double *rayy,double *rpeak) { double pfit[6],a,ax,ay,axx,axy,ayy,cx,cy,det,tr,peak; if ( fit_small_parabola_block(img,j,i,pfit) ) return(1); a=pfit[0],ax=pfit[1],ay=pfit[2], axx=pfit[3],axy=pfit[4],ayy=pfit[5]; det=axx*ayy-axy*axy; tr=axx+ayy; if ( det<=0.0 || tr>=0.0 ) return(1); cx=-(+ayy*ax-axy*ay)/det, cy=-(-axy*ax+axx*ay)/det; if ( fabs(cx)>1 || fabs(cy)>1 ) return(1); peak=a+ax*cx+ay*cy+0.5*(axx*cx*cx+2.0*axy*cx*cy+ayy*cy*cy); *rcx=cx; *rcy=cy; *raxx=axx,*raxy=axy,*rayy=ayy; *rpeak=peak; return(0); } /*****************************************************************************/ static int order_candidates_by_peak_compare(const void *vc1,const void *vc2) { candidate *c1,*c2; c1=(candidate *)vc1,c2=(candidate *)vc2; if ( c1->peak > c2->peak ) return(1); else if ( c1->peak < c2->peak ) return(-1); else return(0); } int order_candidates_by_peak(candidate *cands,int ncand) { qsort(cands,ncand,sizeof(candidate),order_candidates_by_peak_compare); return(0); } /*****************************************************************************/ int cleanup_starlist(star **rstars,int *rnstar) { star *stars,*tstars; int nstar,i,nn; stars=*rstars,nstar=*rnstar; tstars=(star *)malloc(sizeof(star)*nstar); memcpy(tstars,stars,sizeof(star)*nstar); nn=0; for ( i=0 ; i 0 && cands[i].ipoints != NULL ) free(cands[i].ipoints); if ( i0 ) free(cands[i].ipoints); } free(cands); return(0); } /*****************************************************************************/ #define MAX_FIT (MAX_DEVIATION_COEFF+3) /* F=B+A1*I1(x1,y1)+A2*I2(x2,y2)+... */ /* a[] = { B, x1, y1, A1, , x2, y2, A2, , ... } */ /* xpnt = { ix, iy } */ void model_merge(void *xpnt,double *a,double *yy,double *dyda,void *p) { modelparam *mp=p; double wa[MAX_FIT],wdyda[MAX_FIT],wy; int i; *yy=a[0]; dyda[0]=1.0; a++,dyda++; while ( mp->funct != NULL && mp->nshape>0 ) { wa[0]=a[2]; wa[1]=0.0; wa[2]=a[0]; wa[3]=a[1]; a+=3; for ( i=0 ; inshape ; i++,a++ ) { wa[i+4]=*a; } mp->funct(xpnt,wa,&wy,wdyda,mp->param); *yy+=wy; dyda[0]=wdyda[2]; dyda[1]=wdyda[3]; dyda[2]=wdyda[0]; dyda+=3; for ( i=0 ; inshape ; i++,dyda++ ) { *dyda=wdyda[i+4]; } mp++; } } /* F=B+A1*I1(x1,y1)+A2*I2(x2,y2)+... */ /* a[] = { B, x0, y0, A1, , A2, , A3, , ... } */ /* xpnt = { ix, iy } */ void model_combine(void *xpnt,double *a,double *yy,double *dyda,void *p) { modelparam *mp=p; double wa[MAX_FIT],wdyda[MAX_FIT],wy,*dyda0,*a0,amp; int i; dyda0=dyda,a0=a; *yy=a[0]; a+=3; if ( dyda != NULL ) { dyda0[0]=1.0; dyda0[1]=0.0; dyda0[2]=0.0; dyda+=3; } while ( mp->funct != NULL && mp->nshape>0 ) { amp =a[0],a++; wa[0]=amp; wa[1]=0.0; wa[2]=a0[1]; wa[3]=a0[2]; for ( i=0 ; inshape ; i++,a++ ) { wa[i+4]=*a; } if ( dyda != NULL ) mp->funct(xpnt,wa,&wy,wdyda,mp->param); else mp->funct(xpnt,wa,&wy,NULL ,mp->param); *yy+=wy; if ( dyda != NULL ) { dyda0[1]+=wdyda[2]; dyda0[2]+=wdyda[3]; dyda [0] =wdyda[0]; dyda++; for ( i=0 ; inshape ; i++,dyda++ ) { *dyda=wdyda[i+4]; } } mp++; } } /*****************************************************************************/ int refine_candidate_data(fitsimage *img,candidate *wc) { ipoint *wi; double cx,cy,cxx,cxy,cyy,m,mx,my,mxx,mxy,myy,w,x,y,det,x0,y0; int i; if ( wc->ipoints==NULL || wc->nipoint<=0 ) return(1); x0=wc->cx, y0=wc->cy; m=mx=my=0.0; mxx=mxy=myy=0.0; for ( i=0 ; inipoint ; i++ ) { wi=&wc->ipoints[i]; w=(img->data[wi->y][wi->x])-(wc->bg); x=wi->x-x0, y=wi->y-y0; if ( w<=0.0 ) continue; m +=w; mx +=w*(x+0.5); my +=w*(y+0.5); mxx+=w*(x*x+x+1.0/3.0); mxy+=w*(x+0.5)*(y+0.5); myy+=w*(y*y+y+1.0/3.0); } if ( m<=0.0 ) return(0); cx=mx/m; cy=my/m; wc->cx=x0+cx; wc->cy=y0+cy; cxx=mxx/m-cx*cx; cxy=mxy/m-cx*cy; cyy=myy/m-cy*cy; det=cxx*cyy-cxy*cxy; wc->sxx=+cyy/det; wc->sxy=-cxy/det; wc->syy=+cxx/det; return(0); } int refine_candidate_params(fitsimage *img,candidate *cands,int ncand) { int i; if ( img==NULL || img->data==NULL ) return(1); for ( i=0 ; i0.0 ) gdev=sqrt((gs-gm)/(2*gg)); else gdev=0.0; gdel=-gd/(2*gsig*gg); gkap=-gk/(2*gsig*gg); gellip=1.0-(gsig-gdev)/(gsig+gdev); if ( gd*gd+gk*gk == 0.0 ) gpa=0.0; else gpa=0.5*atan2(gkap,gdel)*180.0/M_PI; ws->gfwhm =gsig*SIG_FWHM; ws->gellip=gellip; ws->gpa =gpa; ws->gsig=gsig; ws->gdel=gdel; ws->gkap=gkap; return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ double star_get_unity_flux(starshape *sw) { double flux,gg,c,*mom,is; switch ( sw->model ) { case SHAPE_GAUSS: flux=2.0*M_PI/sw->gs; break; case SHAPE_ELLIPTIC: gg=sw->gs*sw->gs-sw->gd*sw->gd-sw->gk*sw->gk; if ( gg > 0.0 ) flux=2.0*M_PI/sqrt(gg); else flux=0.0; break; case SHAPE_DEVIATED: mom=sw->mom; is=1.0/sw->gs; switch ( sw->order ) { case 2: case 3: c=1.0+0.5*(mom[0]+mom[2])*is; break; case 4: case 5: c=1.0+(0.5*(mom[0]+mom[2])+ 0.25*(0.5*mom[7]+mom[9]+0.5*mom[11])*is)*is; break; default: c=1.0; break; } flux=c*2*M_PI*is; break; default: flux=0.0; } return(flux); } /*****************************************************************************/ int convert_candidates(candidate *cands,int ncand,star **rstars,int *rnstar) { star *stars,*ws; candidate *wc; int nstar,i,j; double gs,gd,gk; stars=(star *)malloc(sizeof(star)*ncand); nstar=ncand; for ( i=0 ; ilocation.gamp=wc->amp; ws->location.gbg =wc->bg; ws->location.gcx =wc->cx; ws->location.gcy =wc->cy; ws->shape.model=SHAPE_ELLIPTIC; ws->shape.order=0; gs=ws->shape.gs=0.5*(wc->sxx+wc->syy); gd=ws->shape.gd=0.5*(wc->sxx-wc->syy); gk=ws->shape.gk=wc->sxy; ws->shape.gl=0.0; for ( j=0 ; jshape.mom[j]=0.0; } #ifdef STAR_MULTIMODEL ws->mshapes=NULL; ws->nmshape=0; #endif star_set_common_shape_params(gs,gd,gk,ws); ws->flux=ws->location.gamp*star_get_unity_flux(&ws->shape); ws->marked=0; ws->cand=wc; } if ( rstars != NULL ) *rstars=stars; if ( rnstar != NULL ) *rnstar=nstar; return(0); } /*****************************************************************************/ fitsh-0.9.2/src/transform.h0000644000175000017500000000315012766340264014237 0ustar apalapal/*****************************************************************************/ /* transform.h */ /*****************************************************************************/ #ifndef __TRANSFORM_H_INCLUDED #define __TRANSFORM_H_INCLUDED 1 #include #define TRANS_POLYNOMIAL 1 #define TRANS_ZOOM 2 #define TRANS_SHRINK 3 #define TRANS_WR_COMMENT 0x01 #define TRANS_WR_DXDY 0x02 #define TRANS_WR_IEEE_32 0x04 #define TRANS_WR_IEEE_64 0x08 /*****************************************************************************/ typedef struct { int type; int order; int nval; double **vfits; double ox,oy,scale; } transformation; /*****************************************************************************/ int transformation_free(transformation *tf); int transformation_read_data(FILE *fr,transformation *tf); int transformation_parse_params(char *params,transformation *tf); int transformation_write_data(FILE *fr,transformation *tf,int flags); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int transformation_check_if_null(transformation *tf); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int transformation_get_jacobi(transformation *tf,double **rjxx,double **rjxy,double **rjyx,double **rjyy); int transformation_eval_normal_2d(double x,double y,transformation *tf,double *rx,double *ry); int transformation_eval_invert_2d(double x,double y,transformation *tf,double *rx,double *ry,double *jxx,double *jxy,double *jyx,double *jyy); /*****************************************************************************/ #endif fitsh-0.9.2/src/fitsmask.c0000644000175000017500000003472012766252347014053 0ustar apalapal/*****************************************************************************/ /* fitsmask.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Mask manipulation extensions to the 'fits.a' library. */ /* (c) 2004-05, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of these and other related */ /* functions in fitsmask.h and fits.h. The library is not standalone, */ /* it depends on fits.a. */ /*****************************************************************************/ #include #include #include #include #include #include "fitsmask.h" /*****************************************************************************/ static char * maskhdr_default="MASKINFO"; #define FITS_MASK_MAX (0x7F) #define FITS_MASK_DEF (0x01) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* char **fits_mask_alloc(int sx,int sy) { int tsize,psize,bsize,cd,cb,snext,pnext; int i,j,rank,arr[2],typesize; void *ret,**pret; rank=2; typesize=sizeof(char); arr[0]=sx; arr[1]=sy; psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { bsize=bsize*arr[i]; psize+=bsize; } psize=psize*sizeof(void *); tsize=psize+typesize*bsize*arr[0]; pret=(void **)malloc(tsize); if ( pret==NULL ) return(NULL); psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { cd=arr[i]; if ( i>1 ) snext=sizeof(void *); else snext=typesize; cb=cd*bsize; pnext=psize+cb; for ( j=0 ; jvtype != FITS_VSTR ) continue; strcpy(buff,fh->vstr); wp=buff; while ( *wp ) { n=sscanf(wp,"%d,%d:%d,%d",&x,&y,&lx,&ly); if ( n==0 ) x=y=lx=ly=0; else if ( n==1 ) { if ( x>0 ) use_diff=1; else if ( x<0 ) data=((-x)&FITS_MASK_MAX); else use_diff=0; x=y=lx=ly=0; } else if ( n==2 ) lx=ly=1; else if ( n==3 ) { if ( lx>1 ) ly=1; else if ( lx<-1 ) ly=-lx,lx=1; else lx=ly=1; } if ( lx>0 && ly>0 ) { if ( use_diff ) x+=xprev,y+=yprev; if ( x<0 ) lx+=x,x=0; if ( y<0 ) ly+=y,y=0; if ( x+lx>=sx ) lx=sx-x; if ( y+ly>=sy ) ly=sy-y; xprev=x,yprev=y; for ( ; ly>0 && lx>0 ; y++,ly-- ) { if ( y=y1 ) continue; for ( sp=mask[y-y0]+x,l=lx ; l>0 ; l--,sp++ ) (*sp) |= data; } } while ( *wp && *wp != 32 ) wp++; while ( *wp==32 ) wp++; }; } return(0); } int fits_mask_mask_from_header(char **mask,fitsheaderset *header,int sx,int sy,char *maskhdr) { int r; if ( sx<=0 || sy<=0 ) return(1); r=fits_mask_mask_from_header_native(mask,header,sx,sy,0,sy,maskhdr); return(r); } char **fits_mask_read_from_header(fitsheaderset *header,int sx,int sy,char *maskhdr) { char **mask; int r; if ( sx<=0 || sy<=0 ) return(NULL); mask=fits_mask_create_empty(sx,sy); if ( mask==NULL ) return(NULL); r=fits_mask_mask_from_header(mask,header,sx,sy,maskhdr); if ( r ) { fits_mask_free(mask); return(NULL); } else return(mask); } int fits_mask_mask_line(char *line,fitsheaderset *header,int sx,int sy,int y0,char *maskhdr) { int r; r=fits_mask_mask_from_header_native(&line,header,sx,sy,y0,y0+1,maskhdr); return(r); } int fits_mask_mask_more_line(char **lines,fitsheaderset *header,int sx,int sy,int y0,int ny,char *maskhdr) { int r; r=fits_mask_mask_from_header_native(lines,header,sx,sy,y0,y0+ny,maskhdr); return(r); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ typedef struct { int x,y; int sx,sy; int value; } block; #define BLOCK_FRAGMENTS 128 static int fits_mask_scan_horizontal(char **mask,int sx,int sy,block **rblocks,int *rnblock) { block *blocks,*wb; int i,j,oj,nj,nblock,nablock,pmv; char *line; nablock=BLOCK_FRAGMENTS; blocks=(block *)malloc(sizeof(block)*nablock);nblock=0; for ( i=0 ; i0 ) { if ( nblock>=nablock ) { nablock+=BLOCK_FRAGMENTS; blocks=(block *)realloc(blocks,sizeof(block)*nablock); } wb=&blocks[nblock]; wb->x=oj,wb->y=i; wb->sx=nj,wb->sy=1; wb->value=pmv; nblock++; } } } *rblocks=blocks, *rnblock=nblock; return(0); } /** old join_blocks algorithm... slow, but seems ok... **/ /*static int fits_mask_join_blocks(block *blocks,int nblock) { int i,j,fi,x,y,sx; for ( i=1 ; i=0 ) { blocks[fi].sy+=blocks[i].sy; blocks[i].sx=-1; } } return(0); }*/ /** new join_blocks algorithm... faster, but probably buggy... **/ static int fits_mask_join_blocks(block *blocks,int nblock) { int i,j,x,y,sx,sy,v; for ( i=0 ; ix,wb->y,wb->sx,wb->sy,wb->value); } */ for ( i=0,wb=blocks ; isx <= 0 ) continue; if ( ! use_diff ) x=wb->x,y=wb->y; else x=wb->x-xprev,y=wb->y-yprev; if ( vprev != wb->value ) { l=sprintf(buff,"-%d ",wb->value); vprev=wb->value; } else l=0; if ( wb->sx==1 && wb->sy==1 ) l+=sprintf(buff+l,"%d,%d",x,y); else if ( wb->sx>1 && wb->sy==1 ) l+=sprintf(buff+l,"%d,%d:%d",x,y,wb->sx); else if ( wb->sx==1 && wb->sy>1 ) l+=sprintf(buff+l,"%d,%d:%d",x,y,-wb->sy); else l+=sprintf(buff+l,"%d,%d:%d,%d",x,y,wb->sx,wb->sy); xprev=wb->x,yprev=wb->y; if ( len==0 ) { strcpy(hdrstr,buff); len=l; } else if ( len+l+1 <= mxl ) { hdrstr[len]=32;strcpy(hdrstr+len+1,buff); len+=l+1; } else { fits_headerset_set_string(header,maskhdr,FITS_SH_ADD,hdrstr,NULL); strcpy(hdrstr,buff); len=l; } } if ( len>0 ) fits_headerset_set_string(header,maskhdr,FITS_SH_ADD,hdrstr,NULL); free(blocks); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ char ** fits_mask_expand_false(char **imask,int sx,int sy,int dis,int imv,int smv,int expand_border) { int i,j,k,l; char **omask; omask=fits_mask_alloc(sx,sy); if ( omask==NULL ) return(NULL); for ( i=0 ; i=sy-dis || j>=sx-dis ) ) omask[i][j] |= smv; else if ( imask[i][j] & imv ) { for ( k=-dis ; k<=dis ; k++ ) { if ( i+k<0 || i+k>=sy ) continue; for ( l=-dis ; l<=dis ; l++ ) { if ( j+l<0 || j+l>=sx ) continue; omask[i+k][j+l] |= smv; } } } } } return(omask); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ char **fits_mask_duplicate(char **mask,int sx,int sy) { char **nm,**wm; nm=fits_mask_alloc(sx,sy); if ( nm==NULL ) return(NULL); for ( wm=nm ; sy>0 ; sy--,wm++,mask++ ) { memcpy(*wm,*mask,sx); } return(nm); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fits_mask_and(char **mask,int sx,int sy,char **other) { char *p,*q; int s; if ( other==NULL ) return(0); for ( ; sy>0 ; sy--,mask++,other++ ) { for ( p=*mask,q=*other,s=sx ; s>0 ; s--,p++,q++ ) { (*p) |= (*q); } } return(0); } int fits_mask_or(char **mask,int sx,int sy,char **other) { char *p,*q; int s; if ( other==NULL ) return(0); for ( ; sy>0 ; sy--,mask++,other++ ) { for ( p=*mask,q=*other,s=sx ; s>0 ; s--,p++,q++ ) { (*p) = ~((~(*p))|(~(*q))); } } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ char ** fits_mask_create_floyd(int sx,int sy,int a,int b,int svm) { char **mask; int i,j,r,sgn,n,w,c,*im[2],*impnt,max,*wp,*l0,*l1,offset; if ( b<=0 ) return(NULL); if ( a<0 || a>b ) return(NULL); if ( sx<=0 || sy<=0 ) return(NULL); mask=fits_mask_create_empty(sx,sy); if ( mask==NULL ) return(NULL); impnt=(int *)malloc(sizeof(int)*sx*2); im[0]=impnt,im[1]=impnt+sx; if ( impnt==NULL ) { fits_mask_free(mask);return(NULL); } max=32768;l0=im[0],l1=im[1]; for ( j=0,r=a*max ; j0 ) offset+=2*b/a; for ( i=-offset,sgn=1 ; i0 ) { for ( j=0 ; j0 ) n+=3; if ( 2*l0[j]0 ) l1[j-1]+=3*w/n; } } else { for ( j=sx-1 ; j>=0 ; j-- ) { n=5; if ( j>0 ) n+=8; if ( j0 ) l0[j-1]+=7*w/n,l1[j-1]+=w/n; if ( j=0 ) { for ( j=0 ; j=max ) mask[i][j]=0; else mask[i][j]=svm; } } wp=l0,l0=l1,l1=wp; } free(impnt); return(mask); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fits_mask_mark_nans(fitsimage *img,char **mask,int setmask) { int i,j,sx,sy; if ( mask==NULL ) return(-1); if ( img==NULL || img->data==NULL ) return(-1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(-1); for ( i=0 ; idata[i][j]) ) { mask[i][j] |= setmask; img->data[i][j]=0.0; } } } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int fits_mask_expand(char ***rmask,int sx,int sy,int nx,int ny,int fill) { char **mask; size_t ns; int i; if ( nx=0 ; i-- ) { memmove(((char *)(mask+ny))+i*nx,((char *)(mask+sy))+i*sx,sx); if ( nx>sx ) memset(((char *)(mask+ny))+i*nx+sx,fill,nx-sx); } for ( i=sy ; isx || ny>sy ) return(-1); else if ( nx==sx && ny==sy ) return(0); mask=*rmask; for ( i=0 ; i=ty ) { memset(line,outer,tx); return(0); } else { int l,c; l=tx; while ( l>0 ) { if ( x0<0 ) { c=-x0; if ( c>l ) c=l; memset(line,outer,c); line+=c; l-=c; x0+=c; } else if ( x0>=tx ) { c=l; memset(line,outer,c); line+=c; l-=c; x0+=c; } else { c=tx-x0; if ( c>l ) c=l; memcpy(line,mask[y0]+x0,c); line+=c; l-=c; x0+=c; } } return(0); } } int fits_mask_trim(char ***rmask,int sx,int sy,int x0,int y0,int nx,int ny,int outer) { char **mask,*line; int tx,ty,i; mask=*rmask; tx=(nx>sx?nx:sx); ty=(ny>sy?ny:sy); fits_mask_expand(&mask,sx,sy,tx,ty,outer); line=(char *)malloc(tx); if ( x0 != 0 || y0 != 0 ) { if ( y0>0 ) { for ( i=0 ; i=0 ; i-- ) { fits_mask_copy_line(mask,tx,ty,x0,i+y0,line,outer); memcpy(mask[i],line,tx); } } } free(line); fits_mask_shrink(&mask,tx,ty,nx,ny); *rmask=mask; return(0); } /*****************************************************************************/ int fits_mask_is_clean(char **mask,int sx,int sy) { char *line; int i; line=(char *)malloc(sx); memset(line,0,sx); for ( i=0 ; i #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "fitsmask.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "math/spline/biquad.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/point.h" #include "math/polygon.h" #include "statistics.h" #include "magnitude.h" #include "tensor.h" #include "common.h" #include "apphot.h" #include "kernel.h" #include "weight.h" #include "fiphot.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int get_kernel_block_coords(int id,int *rbx,int *rby) { int bx,by,fs,bl,hs; if ( id<=0 ) bx=by=0; else { hs=1,fs=3;bl=8;id--; while ( 1 ) { if ( id=bl-fs ) bx=-hs+id-bl+fs,by=hs; else { id-=fs; by=-hs+1+id/2; if ( id%2==0 ) bx=-hs; else bx=+hs; } break; } else { id-=bl,hs++, fs+=2,bl+=8; } }; } *rbx=bx, *rby=by; return(0); } int get_kernel_block_id(int bx,int by) { int hs,b; if ( bx==0 && by==0 ) return(0); hs=0; if ( +bx>hs ) hs=+bx; if ( -bx>hs ) hs=-bx; if ( +by>hs ) hs=+by; if ( -by>hs ) hs=-by; b=(2*hs-1)*(2*hs-1); if ( by==-hs ) return(b+hs+bx); else if ( by==+hs ) return(b+7*hs-1+bx); else if ( bx==-hs ) return(b+2*hs+1+2*(hs+by-1)+0); else if ( bx==+hs ) return(b+2*hs+1+2*(hs+by-1)+1); else return(-1); } /*****************************************************************************/ double optimal_aperture_xi_approx(double m) { double x,xi,b,d,c,q,w; x=log(m); b=2.316,d=-1.914,q=3.0; w=fabs(x-d); c=2.512862417; xi=sqrt(pow(b*b+pow(w,q),1.0/q)-(x-d)+c); return(xi); } double optimal_aperture_xi(double m,int n) { double xi,k,t; int i; xi=optimal_aperture_xi_approx(m); for ( i=0 ; isubg ) subg=ix; if ( iy>subg ) subg=iy; } subg++; subpixeldata=tensor_alloc_2d(double,subg,subg); for ( i=0 ; iflux,pf->fluxerr,mf,&pf->mag,&pf->magerr); } } return(0); } /*****************************************************************************/ int add_to_data_weight(double **data,char **mask,int sx,int sy, int hsize,int grid,weight *wg,double mul) { int i,j,fsize,ix,iy; if ( data==NULL || wg==NULL ) return(1); fsize=grid*(2*hsize+1); for ( i=0 ; iiy; if ( iy<0 || iy>=sy ) continue; for ( j=0 ; jix; if ( ix<0 || ix>=sx ) continue; if ( mask != NULL && mask[iy][ix] ) continue; data[iy][ix] += mul * wg->iarr[i][j]; } } return(0); } int add_to_image_weights(fitsimage *img,char **mask,weightlist *wl,double mul) { int i; if ( img==NULL || img->data==NULL ) return(1); if ( img->sx<=0 || img->sy<=0 ) return(1); if ( wl==NULL || wl->weights==NULL ) return(0); for ( i=0 ; inweight ; i++ ) { add_to_data_weight(img->data,mask,img->sx,img->sy, wl->hsize,wl->grid,&wl->weights[i],mul); } return(0); } /*****************************************************************************/ /***** typedef struct { fitsimage *img; char **mask; weightlist *wl; int weightusage; int is_calc_opt_apert; apgeom *inaps; int numap; int bkhsize; double gain,sigma; xphotpar *xpp; double **bqc; } phot_parallel_param; *****/ int ringmask_subtract(char **ringmask,int sx,int sy,double x,double y,double r) { int i,j,i0,i1,j0,j1; double r2,dx,dy; r2=r*r; i0=(int)(y-r-1.0); if ( i0<0 ) i0=0; i1=(int)(y+r+1.0); if ( i1>sy ) i1=sy; j0=(int)(x-r-1.0); if ( j0<0 ) j0=0; j1=(int)(x+r+1.0); if ( j1>sx ) j1=sx; for ( i=i0 ; isy ) i1=sy; j0=(int)(x-r-1.0); if ( j0<0 ) j0=0; j1=(int)(x+r+1.0); if ( j1>sx ) j1=sx; for ( i=i0 ; i0.0 ) r=dradius; else { if ( inaps != NULL ) aps=inaps; else aps=ps[n].inaps; if ( aps==NULL ) continue; /* however, unexpected. */ if ( dradius<0.0 ) r=aps[a].ra; else r=aps[a].r0; } ringmask_coadd(ringmask,sx,sy,ps[n].x,ps[n].y,r); } return(ringmask); } int do_photometry(fitsimage *img,char **mask, photstar *ps,int np,weightlist *wl,int weightusage,int is_calc_opt_apert, apgeom *inaps,int numap, spatialgain *sg,double sigma,xphotpar *xpp) { int i,j,k,jp,sx,sy,r; apphotpar ap; apgeom *aps; photflux *pf,*wpf; double bgarea,bgflux,bgmedian,bgsigma,gain; double area,flux,fluxerr,cx,cy,dx,dy,cfd2; double **bqc; weight *ww; double **aphdata,**aphwsum,grid2,igrid2; char **aphmask; char ***ringmasks; int hsize,fsize,grid,wfsize; if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); if ( xpp->use_biquad ) { bqc=tensor_alloc_2d(double,sx*2+1,sy*2+1); if ( bqc==NULL ) return(-1); biquad_coeff(img->data,sx,sy,bqc,NULL); weightusage &= ~(USE_WEIGHT_SUBTRACTED|USE_WEIGHT_WEIGHTED); } else bqc=NULL; if ( wl==NULL || ! weightusage ) wl=NULL,weightusage=0; memcpy(&ap.bgm,&xpp->bgm,sizeof(bgmode)); if ( wl != NULL ) { grid=wl->grid; wfsize=grid*(2*wl->hsize+1); } else { grid=0; wfsize=0; } if ( weightusage & USE_WEIGHT_SUBTRACTED ) { add_to_image_weights(img,mask,wl,-1.0); cfd2=xpp->wconfdist*xpp->wconfdist; } else cfd2=0.0; if ( weightusage & USE_WEIGHT_WEIGHTED ) { hsize=0; if ( inaps != NULL ) { aps=inaps; for ( j=0 ; jhsize ) hsize=k; } } else { for ( i=0 ; ihsize ) hsize=k; } } } fsize=grid*(2*hsize+1); aphdata=(double **)tensor_alloc_2d(double,fsize,fsize); aphmask=(char **)tensor_alloc_2d(char,fsize,fsize); aphwsum=(double **)tensor_alloc_2d(double,2*wl->hsize+1,2*wl->hsize+1); } else { hsize=fsize=0; grid=1; aphdata=NULL; aphwsum=NULL; aphmask=NULL; } if ( xpp->is_disjoint_rings ) { ringmasks=(char ***)malloc(sizeof(char **)*numap); for ( j=0 ; jis_disjoint_apertures ) { ringmasks=(char ***)malloc(sizeof(char **)*numap); for ( j=0 ; jdisjoint_radius > 0.0 ) { ringmasks=(char ***)malloc(sizeof(char **)*numap); for ( j=0 ; jdisjoint_radius); } } else ringmasks=NULL; grid2=(double)(grid*grid); igrid2=1.0/grid2; for ( i=0 ; iorder,sg->coeff,0.5*(double)sx,0.5*(double)sy,0.5*(double)sx); if ( 0vmin && gainvmin ) gain=sg->vmin; ap.gain=gain; if ( weightusage & USE_WEIGHT_SUBTRACTED ) { ww=weight_get_closest(wl,cx,cy); dx=cx-ww->x,dy=cy-ww->y; if ( cfd2<=0.0 || dx*dx+dy*dydata,mask,sx,sy,wl->hsize,wl->grid,ww,+1.0); else ww=NULL; } else ww=NULL; /* if ( weightusage & USE_WEIGHT_WEIGHTED ) { int ix0,iy0,i,j; int ix,iy,wx,wy; weight *ww; ww=weight_get_closest(wl,cx,cy); ix0=((int)floor(cx))-hsize; iy0=((int)floor(cy))-hsize; for ( i=0 ; iiarr[i][j]; } } for ( i=0 ; i=sx || iy>=sy ) { aphmask[i][j] = MASK_OUTER; aphdata[i][j] = 0.0; continue; } else if ( mask != NULL ) { aphmask[i][j] = mask[iy][ix]; } else { aphmask[i][j] = 0; } aphdata[i][j]=img->data[iy][ix]*igrid2; wx=j+grid*(-hsize+wl->hsize); wy=i+grid*(-hsize+wl->hsize); if ( wx>=0 && wy>=0 && wxiarr[wy][wx]; aphdata[i][j]-=aphwsum[wy/grid][wx/grid]*igrid2; } } } } */ for ( j=0 ; jag.r0=ap.r0; wpf->ag.ra=ap.ra; wpf->ag.da=ap.da; for ( k=0,jp=-1 ; k=0 ) { bgarea=pf[jp].bgarea, bgflux=pf[jp].bgflux, bgmedian=pf[jp].bgmedian, bgsigma=pf[jp].bgsigma; atot=pf[jp].atot, abad=pf[jp].abad; r=0; } else if ( (! xpp->use_sky) && ringmasks != NULL ) { r=aperture_photometry_back_ring(img->data,mask,sx,sy,cx,cy, &ap,&bgarea,&bgflux,&bgmedian,&bgsigma, &atot,&abad,ringmasks[j]); } else if ( (! xpp->use_sky) ) { if ( apgeom_type==APGEOM_TYPE_CIRCULAR ) { r=aperture_photometry_back_ring(img->data,mask,sx,sy,cx,cy, &ap,&bgarea,&bgflux,&bgmedian,&bgsigma, &atot,&abad,NULL); } else if ( apgeom_type==APGEOM_TYPE_POLYGON ) { r=aperture_photometry_back_polygons(img->data,mask,sx,sy,cx,cy, &ap,&bgarea,&bgflux,&bgmedian,&bgsigma, &atot,&abad,NULL); } else r=1; } else { if ( apgeom_type==APGEOM_TYPE_CIRCULAR ) bgarea=M_PI*(2.0*ap.ra*ap.da+ap.da*ap.da); else bgarea=polygon_area(ap.da_poly,ap.nda)-polygon_area(ap.ra_poly,ap.nra); bgflux=xpp->sky*bgarea; bgmedian=xpp->sky; bgsigma=0.0; atot=(int)bgarea; abad=0; r=0; } background=bgmedian; if ( r ) { wpf=&pf[j]; wpf->flag=MASK_NOBACKGROUND; wpf->rtot=0; wpf->rbad=0; wpf->rign=0; wpf->atot=0; wpf->abad=0; continue; } wpf=&pf[j]; wpf->bgmedian=bgmedian, wpf->bgsigma=bgsigma; wpf->bgflux=bgflux; wpf->bgarea=bgarea; wpf->atot=atot; wpf->abad=abad; /* if ( xpp->is_disjoint_apertures ) ringmask_subtract(ringmasks[j],sx,sy,cx,cy,ap.ra); */ wpf=&pf[j]; wpf->flag=0; if ( bqc != NULL ) { /* if ( xpp->is_disjoint_apertures || xpp->disjoint_radius>0.0 ) r=aperture_photometry_flux_biquad(bqc,mask,sx,sy,cx,cy,ap.r0,&area,&flux,&rtot,&rbad,&rign,xpp->maskignore,ringmasks[j]); else */ r=aperture_photometry_flux_biquad(bqc,mask,sx,sy,cx,cy,ap.r0,&area,&flux,&rtot,&rbad,&rign,xpp->maskignore,NULL); } else if ( ! (weightusage & USE_WEIGHT_WEIGHTED) ) { /* if ( xpp->is_disjoint_apertures || xpp->disjoint_radius>0.0 ) r=aperture_photometry_flux(img->data,mask,sx,sy,cx,cy,ap.r0,&area,&flux,&rtot,&rbad,&rign,xpp->maskignore,xpp->subpixeldata,xpp->subg,ringmasks[j]); else */ if ( apgeom_type==APGEOM_TYPE_CIRCULAR ) r=aperture_photometry_flux_circle(img->data,mask,sx,sy,cx,cy,ap.r0,&area,&flux,&out,background,&rtot,&rbad,&rign,xpp->maskignore,xpp->subpixeldata,xpp->subg,NULL); else if ( apgeom_type==APGEOM_TYPE_POLYGON ) r=aperture_photometry_flux_polygon(img->data,mask,sx,sy,cx,cy,ap.r0_poly,ap.nr0,&area,&flux,&out,background,&rtot,&rbad,&rign,xpp->maskignore,NULL); else { r=-1; rtot=rbad=rign=0; } } else { double r0; double ccx,ccy,cx0,cy0,bg; int ix0,iy0,i,j; int ix,iy,wx,wy; weight *ww; cx0=floor(cx); cy0=floor(cy); ccx=(double)grid*((cx-cx0)+(double)hsize); ccy=(double)grid*((cy-cy0)+(double)hsize); r0 =(double)grid*ap.r0; ww=weight_get_closest(wl,cx,cy); ix0=(int)cx0-hsize; iy0=(int)cy0-hsize; for ( i=0 ; iiarr[i][j]; } } bg=bgmedian*igrid2; for ( i=0 ; i=sx || iy>=sy ) { aphmask[i][j] = MASK_OUTER; aphdata[i][j] = 0.0; continue; } else if ( mask != NULL ) { aphmask[i][j] = mask[iy][ix]; } else { aphmask[i][j] = 0; } aphdata[i][j]=img->data[iy][ix]*igrid2-bg; wx=j+grid*(-hsize+wl->hsize); wy=i+grid*(-hsize+wl->hsize); if ( wx>=0 && wy>=0 && wxiarr[wy][wx]/aphwsum[wy/grid][wx/grid]; } aphdata[i][j]+=bg; } } r=aperture_photometry_flux_circle(aphdata,aphmask,fsize,fsize,ccx,ccy,r0,&area,&flux,&out,background,&rtot,&rbad,&rign,xpp->maskignore,xpp->subpixeldata,xpp->subg,NULL); } wpf->rtot=rtot; wpf->rbad=rbad; wpf->rign=rign; wpf->flag |= r; flux -= bgmedian*area*igrid2; wpf->flux=flux; if ( flux<=0.0 ) { wpf->fluxerr=0.0; } else { fluxerr=sqrt((0.0fluxerr=fluxerr; } if ( 0.0 < out.fw && 0 < flux ) { double mx,my,mxx,mxy,myy,sxx,syy,sxy,ac0,w; mx=out.fwx/out.fw; my=out.fwy/out.fw; wpf->cntr_x=mx+cx; wpf->cntr_y=my+cy; mxx=out.fwxx/out.fw; mxy=out.fwxy/out.fw; myy=out.fwyy/out.fw; sxx=mxx-mx*mx; sxy=mxy-mx*my; syy=myy-my*my; ac0=area*bgsigma/flux; wpf->cntr_x_err=sqrt((0.0cntr_y_err=sqrt((0.0cntr_width=0.0; wpf->cntr_w_err=-1.0; } else { double sig2; double a,b,c,ws,wd,wk; a=(sxx+syy)/2; b=(sxx-syy)/2; c=sxy; ws=sqrt(0.5*(a+sqrt(a*a-b*b-c*c))); wd=b/(2*ws); wk=c/(2*ws); wpf->cntr_width=ws; wpf->cntr_w_d=wd; wpf->cntr_w_k=wk; sig2=sqrt(w); wpf->cntr_w_err=sqrt((0.0cntr_x=0.0; wpf->cntr_y=0.0; wpf->cntr_x_err=-1.0; wpf->cntr_y_err=-1.0; wpf->cntr_width=-1.0; wpf->cntr_w_err=-1.0; } /* if ( xpp->is_disjoint_apertures ) ringmask_coadd(ringmasks[j],sx,sy,cx,cy,ap.ra); */ } /* for ( j=0 ; jdata,mask,sx,sy,wl->hsize,wl->grid,ww,-1.0); if ( is_calc_opt_apert && numap==1 && ( ! pf[0].flag ) ) { double r0opt; if ( 0.0=0 ; j-- ) { if ( ringmasks[j] != NULL ) tensor_free(ringmasks[j]); } free(ringmasks); ringmasks=NULL; } if ( aphmask != NULL ) tensor_free(aphmask); if ( aphdata != NULL ) tensor_free(aphdata); if ( bqc != NULL ) tensor_free(bqc); if ( weightusage & USE_WEIGHT_SUBTRACTED ) add_to_image_weights(img,mask,wl,+1.0); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int do_subtracted_photometry(fitsimage *img,char **mask,photstar *ps,int np, apgeom *inaps,int numap, spatialgain *sg,xphotpar *xpp,kernellist *klist) { int i,j,k,jp,bx,by,sx,sy,r,atot,abad,rtot,rbad,rign,flag; apphotpar ap; apgeom *aps; int n; photflux *pf,*wpf; double bgarea,bgflux,bgmedian,bgsigma,gain; double area,flux,fluxerr,cx,cy,kx,ky,flux0,sflux,kflux; double **bqc; photflux **fluxarr; double **kernarr; int hsize,fsize; if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); if ( xpp->use_biquad ) { bqc=tensor_alloc_2d(double,sx*2+1,sy*2+1); if ( bqc==NULL ) return(-1); biquad_coeff(img->data,sx,sy,bqc,NULL); } else bqc=NULL; memcpy(&ap.bgm,&xpp->bgm,sizeof(bgmode)); if ( klist != NULL ) { hsize=0; for ( k=0 ; knkernel ; k++ ) { if ( klist->kernels[k].hsize>hsize ) hsize=klist->kernels[k].hsize; } } else hsize=0; fsize=2*hsize+1; fluxarr=(photflux **)tensor_alloc_2d(photflux,fsize,fsize); kernarr=(double **)tensor_alloc_2d(double ,fsize,fsize); for ( i=0 ; iorder,sg->coeff,0.5*(double)sx,0.5*(double)sy,0.5*(double)sx); if ( sg->vmin>0 && gainvmin ) gain=sg->vmin; ap.gain=gain; for ( j=0 ; jflag=0; wpf->atot=0; wpf->abad=0; wpf->rtot=0; wpf->rbad=0; wpf->rign=0; ap.r0=aps[j].r0, ap.ra=aps[j].ra, ap.da=aps[j].da; for ( k=0,jp=-1 ; k=0 ) { bgarea =pf[jp].bgarea, bgflux =pf[jp].bgflux, bgmedian=pf[jp].bgmedian, bgsigma =pf[jp].bgsigma; atot =pf[jp].atot; abad =pf[jp].abad; r=0; } else r=aperture_photometry_back_ring(img->data,mask,sx,sy,cx,cy,&ap,&bgarea,&bgflux,&bgmedian,&bgsigma,&atot,&abad,NULL); if ( r ) { wpf->flag=MASK_NOBACKGROUND; continue; } flag=0; rtot=0; rbad=0; rign=0; for ( by=-hsize ; by<=hsize ; by++ ) { for ( bx=-hsize ; bx<=hsize ; bx++ ) { double a,f; int rt,rb,ri; if ( xpp->use_biquad ) r=aperture_photometry_flux_biquad(bqc,mask,sx,sy,cx+bx,cy+by,ap.r0,&a,&f,&rt,&rb,&ri,xpp->maskignore,NULL); else r=aperture_photometry_flux_circle(img->data,mask,sx,sy,cx+bx,cy+by,ap.r0,&a,&f,NULL,0.0,&rt,&rb,&ri,xpp->maskignore,NULL,0,NULL); if ( rt>rtot ) rtot=rt; if ( rb>rbad ) rbad=rb; if ( ri>rign ) rign=ri; fluxarr[hsize+by][hsize+bx].flux=f-bgmedian*a; fluxarr[hsize+by][hsize+bx].flag=r; fluxarr[hsize+by][hsize+bx].bgarea=a; flag |= r; } } if ( flag ) { wpf->flag |= flag; wpf->flux=0.0; wpf->fluxerr=0.0; continue; } if ( klist == NULL ) { flux=fluxarr[0][0].flux; kernarr[0][0]=1.0; kflux=1.0; } else { int c; kernel *k; double kcoeff; for ( by=0 ; bykernels ; cnkernel ; c++,k++ ) { if ( k->type==KERNEL_BACKGROUND ) continue; kcoeff=eval_2d_poly(kx,ky,k->order,k->coeff,klist->ox,klist->oy,klist->scale); if ( k->type==KERNEL_IDENTITY ) kernarr[hsize][hsize]+=kcoeff; else { for ( by=-k->hsize ; by<=+k->hsize ; by++ ) { for ( bx=-k->hsize ; bx<=+k->hsize ; bx++ ) { kernarr[hsize+by][hsize+bx]+=kcoeff*k->image[k->hsize+by][k->hsize+bx]; } } } } kflux=0.0; for ( by=0 ; byatot=atot; wpf->abad=abad; wpf->rtot=rtot; wpf->rbad=rbad; wpf->rign=rign; wpf->bgmedian=bgmedian, wpf->bgsigma=bgsigma; wpf->bgflux=bgflux; wpf->bgarea=bgarea; wpf->ag.r0=ap.r0; wpf->ag.ra=ap.ra; wpf->ag.da=ap.da; if ( ps[i].rfflux[j].flag ) { wpf->flag |= ps[i].rfflux[j].flag; wpf->flux=0.0; wpf->fluxerr=0.0; continue; } flux0=ps[i].rfflux[j].flux; flux = flux0 + sflux; if ( flux<=0.0 || flux0<=0.0 ) { wpf->flux=0.0, wpf->fluxerr=0.0; } else { fluxerr=sqrt((0.0flux=flux, wpf->fluxerr=fluxerr; } wpf->flag=0; } ps[i].n=n; } if ( bqc != NULL ) tensor_free(bqc); return(0); } /*****************************************************************************/ int do_magnitude_fit(photstar *stars,int nstar, magfitparams *mfp,int sx,int sy,magfitstat *mfs) { int a,nvar,i,j,n,maxorder,k,l,v,iiter; double **amatrix,*bvector,*fvars,*monoms,yvar; double ox,oy,scale,dmag,cmul,w; photstar *s; photflux *fi,*fr; double *dmags,*wghts,*smags; nvar=0; maxorder=0; for ( j=0 ; j<=mfp->norder ; j++ ) { nvar+=(mfp->orders[j]+1)*(mfp->orders[j]+2)/2; if ( maxorderorders[j] ) maxorder=mfp->orders[j]; } /* n: total (maximal) number of apertures */ n=0; for ( i=0 ; instar=nstar; mfs->naperture=n; mfs->ninit=(int *)malloc(sizeof(int)*n); mfs->nrejs=(int *)malloc(sizeof(int)*n); for ( a=0 ; aninit[a]=0; mfs->nrejs[a]=0; } } for ( a=0 ; an < a || s->fluxes==NULL || s->rfflux==NULL ) continue; fi=&s->fluxes[a]; fr=&s->rfflux[a]; if ( fi->flag || fr->flag || fi->flux<=0.0 || fr->flux<=0.0 ) continue; dmag=log(fi->flux/fr->flux); dmags[i]=dmag; w=sqrt(fr->flux); wghts[i]=w; mfs->ninit[a]++; } for ( iiter=0 ; iiter<=mfp->niter ; iiter++ ) { for ( k=0 ; kfluxes[a]; fr=&s->rfflux[a]; dmag=dmags[i]; v=0; cmul=1.0; w=wghts[i]; /* weight */ for ( j=0 ; j<=mfp->norder ; j++ ) { eval_2d_monoms(s->x,s->y,mfp->orders[j],fvars+v,ox,oy,scale); l=(mfp->orders[j]+1)*(mfp->orders[j]+2)/2; for ( k=0 ; kref_col; } yvar=dmag; for ( k=0 ; kniter ) { double s0,s1,s2,d; for ( i=0 ; ifluxes[a]; fr=&s->rfflux[a]; v=0; cmul=1.0; for ( j=0 ; j<=mfp->norder ; j++ ) { eval_2d_monoms(s->x,s->y,mfp->orders[j],fvars+v,ox,oy,scale); l=(mfp->orders[j]+1)*(mfp->orders[j]+2)/2; for ( k=0 ; kref_col; } dmag=0.0; for ( k=0 ; k= s2*mfp->sigma ) { wghts[i]=-1.0; mfs->nrejs[a]++; } } } } for ( i=0 ; in < a || s->fluxes==NULL || s->rfflux==NULL ) continue; fi=&s->fluxes[a]; fr=&s->rfflux[a]; if ( fi->flux<=0.0 || fr->flux<=0.0 ) continue; v=0; cmul=1.0; for ( j=0 ; j<=mfp->norder ; j++ ) { eval_2d_monoms(s->x,s->y,mfp->orders[j],fvars+v,ox,oy,scale); l=(mfp->orders[j]+1)*(mfp->orders[j]+2)/2; for ( k=0 ; kref_col; } dmag=dmags[i]; for ( k=0 ; kflux=fr->flux*exp(dmag); } } free(wghts); free(smags); free(dmags); vector_free(monoms); vector_free(fvars); vector_free(bvector); matrix_free(amatrix); return(0); } /*****************************************************************************/ int fprint_fiphot_usage(FILE *fw) { fprintf(fw, "Usage:\tfiphot [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[[-i|--input] |-] [-o|--output |-]\n" "\t[-V|--verbose] [-C|--comment]\n" "\t-L|--input-list |- [--output-list |-]\n" "\t{[]|-r [] -s [...] [--frame ]}\n"); fprintf(fw, "General parameters:\n" "\t[-a|--aperture[s] r01[:ra1[:da1]][,r02[:ra2[:da2]][,...]] ]\n" "\t[--sky-fit {mean|mode|median,iterations=n,lower=l,upper=u,sigma=s}|\n" "\t |force=]\n" "\t[-j|--disjoint-rings | --disjoint-apertures | -x|--disjoint-radius ]\n" "\t[-z|--zoom ] [-k|--spline] [--aperture-mask-ignore ]\n" "\t[-g|--gain [,]|auto] [--mag-flux ,]\n" "\t[-u [--normalize]]\n"); fprintf(fw, "Input and output format parameters:\n" "\t[--col-xy <>,<>] [--col-ap <>[:<>[:<>]]...] [--col-id <>]\n" "\t[--col-mag <> [--col-magerr <>] [--col-color <>]]\n" "\t[-F|--format [XYIS-],[MmBbFfAaEeSsWwDK-]] [--nan-string ]\n" "\t[--serial ]\n"); fprintf(fw, "Post-photometry magnitude transformation parameters (a.k.a. 'magfit'):\n" "\t[--magfit orders=[:[:[:]]],niter=,sigma=]\n"); fprintf(fw, "Parameters of optimal aperture determination:\n" "\t[-d|--skysigma ] [-f|--fwhm ]\n"); fprintf(fw, "Weight stamps:\n" "\t[--input-weight ]\n" "\t[--weight-usage [weighting],[subtraction],confidence=]\n"); return(0); } longhelp_entry fiphot_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-i, --input ", "Name of the input FITS image file." }, { "Simple aperture photometry:", NULL }, { "-L, --input-list ", "Name of the input coordinate list file." }, { "--col-xy ,", "Column indices for centroid coordinates. The coordinates read from " "this file follows the native coordinating scheme (which is not " "the same as e.g. in IRAF), namely the lower-left corner of the " "lower-left pixel has the coordinate of (0,0) while the center of the " "lower-left pixel has the coordinate of (0.5,0.5). Programs like IRAF " "use the coordinate (1,1) for the center of the lower-left pixel. " }, { "--col-ap ,,...", "Column indices for various apertures. In each such column, there " "must be three colon-separated number, for the radius of the aperture, " "inner radius for the background annulus and the thickness of the " "annulus, respectively. This option is not mandatory, all of the " "objects can be measured with the same set of apertures, see also " "-a|--apertures for more details. " }, { "--col-id ", "Column index for object identifier. " }, { "--col-mag, --col-magnitude ", "Column index for reference magnitude. " }, { "--col-col, --col-color ", "Column index for photometric color." }, { "--col-err, --col-error ", "Column index for magnitude uncertainty." }, { "-z, --zoom ", "Mutiply both the input centroid coordinates and aperture/annulus" "radii by the given integer factor. " }, { "--serial ", "Serial identifier for the whole photometry procedure. Can be any " "arbitrary string and used only in the formatted output (see " "-F|--format for more details)." }, { "-F, --format, --format-output ,", "List of output format tags. The formatted (user-friendly) output " "photometry contains a few columns containing the data related to " "the object, which followed by a the per-aperture photometry " "results. See \"Format tags\" for the list of format tags used here." }, { "--nan ", "String which is used to denote bad photometry. By default, objects " "on which photometry cannot be performed (due to various reasons, e.g. " "the object is off from the image, the background level cannot be " "determined or there are bad pixels in the aperture itself), " "are marked by a simple dash ('-') in the output file. " }, { "-M, --input-mask ", "Input mask file to co-add to the mask of the input image. Useful for " "marking pixels to be ignored from the photometry process beyond the " "ones which are previously marked in the input image." }, { "-a, --aperture, --apertures ", __extension__ "List of circular apertures to be involved in the photometry. " "Each circular aperture " "is defined by three numbers: the radius of the aperture, and the " "inner radius and \"thickness\" of the annulus used for sky background " "estimation. The aperture specifications must be spearated by " "commas while these three numbers must be separated by colons. " "E.g. to perform aperture photometry on a series of apertures with " "a radius of 1.5, 2.0 and 2.5 pixels, where all of the annuli " "have an inner and outer radius of 6.5 and 12 pixels (i.e. the " "thickness is 5.5 pixels), one should write " "1.5:6.5:5.5,2.0:6.5:5.5,2.5:6.5:5.5 as an argument for this option." }, { "-a, --aperture, --apertures ", __extension__ "List of polygon shaped apertures. Polygons can only be simple " "(i.e. non-intersection) or weakly simple polygons which are defined " "throughout the form of P[x1,y1,...,xn,yn] or polygon[x1,y1,...,xn,yn]. " "The (x,y)=(0,0) point always refer to the aperture centroid as read " "from the input list (see --input-list above). There are two types " "of pre-defined simple polygons which is useful in astronomical image " "processing. The first definition is Q[R,n,alpha] or regular[R,n,alpha] " "which implies a regular polygon having n sides and an area equivalent to " "a circle with a radius of R and the polygon is rotated w.r.t the xy-plane " "by \"alpha\" degrees. In the asymptotic limit of n -> infinity, this " "aperture is equivalent to a circular aperture. " "The second type is T[R,n,dx,dy] or trail[R,n,dx,dy] where " "this definition implies a nearly oval racetrack-shaped aperture with a " "curvature radius of R, a net length of L=sqrt(dx^2+dy^2), the round part is approximated " "by a regular n-gon and the whole shape is rotated w.r.t the x+ axis as " "defined by the (dx,dy) vector. In the limit of L -> 0, this shape is equivalent to " "the aperture definition of regular[R,n,alpha]. The trail[....] shape " "is useful to perform photometry on asteroid or meteoroid trails. " "One should note that circular and polygon aperture definitions " "cannot be mixed. In addition, it should be noted that in case of " "polygon-shaped apertures, the second definition implies the inner edge " "of the background area and the third definition implies the outer edge " "of the background area. For instance, the aperture 3:5:5 can be ideal " "for point sources, the aperture trail[3,16,3.0,4.0]:trail[5,16,3.0,4.0]:trail[10,16,3.0,4.0] " "can be optimal for a asteroid trail on the same image that has a net " "length of 5.0 pixels and parallel with the vector (3.0,4.0). In this " "case, the equivalent radius of the third part is set to 10 which is " "equivalent to the 5+5=10 pixels of the radius of the outer annulus " "in the definition of 3:5:5." }, { "-g, --gain, --gain-poly ", __extension__ "The polynomial describing the gain level throughout the image. " "Altough during the image readout process, the electron <-> ADU " "conversion ratio has a fixed value, during the calibration process " "when the vignetting is strong, the ADU levels may substantially " "change. The comma-separated numbers in the gain polynomial should " "denote the coefficients for the monomials 1, x, y, 1/2x^2, xy, ... " "(the standard order for 2 dimensional polynomial coefficients), " "where x and y are the normalized coordinates (i.e. zero at the " "center of the image, x = +/- 1 at the right/left edge of the image " "and y is scaled appropriately keeping the aspect ratio). Note that " "the number of coefficients should be 1, 3, 6, 10, ... and so on, " "for zeroth, first, second, third... order variations, respectively." "Specifying zero or negative gain will imply an \"infinitely large\" " "gain, thus data are treated as being affected only by instrumental " "noise and lack intrinsic photon noise. " }, { "--gain-vmin ", "The minimal value for the gain level. If the polynomial describing " "the spatial gain variations is evaluated on the regular image domain " "and yielded a smaller value than this given number, this " "will be used as gain level. In certain optical systems, the vignetting " "can be well described by second-order polynomial coefficients except " "at the very corners of the image. In such a situation this minimal gain " "is quite useful. " }, { "--mag-flux ,", "Magnitude - flux conversion level. The specified magnitude will " "be equivalent to the specified flux level. " }, { "--sky-fit ", "This argument is followed by a set of parameters for the " "sky (i.e. background level) fitting algorithm. See \"Sky fitting " "parameters\" below for more details. " }, { "--aperture-mask-ignore ", "This switch is followed by a space separated list of standard " "masks which should be ignored if such a pixel is marked so in the " "aperutre. In practice, it might be useful to put saturated objects " "into the set of \"good\" stars. " }, { "-o, --output ", "Name of the output file containing the results of the aperture " "photometry. The format and content of this file can be arbitrarily " "set, see -F|--format." }, { "--output-raw-photometry ", __extension__ "Name of the output file containing the all of the low-level photometric " "information in a fixed format. From this file, one can derive all of the " "quantities which are written to the \"normal\" output photometry " "file. The main purpose of this file is to be an input for image " "subtraction based photometry, i.e. the photometric information for " "the reference image is supposed to be stored in this format and " "the successive calls of `fiphot` on the subtracted residual images " "read this information in order to derive the final photometric " "information. See the subsection \"Photometry on subtracted/convolved " "images\" about more details on the image subtraction " "based photometry." }, { "Note that the literal \"auto\" argument can also be used after the " "-g|--gain switch. In this case, `fiphot` tries to figure out the " "gain polynomial from the GAINPOLY and GAIN keywords (in this order) " "as well as the minimal value for the gain from the GAINVMIN keyword.", NULL }, { "", NULL }, { "Format tags for generic object data:", NULL }, { "I", "identifier" }, { "S", "serial identifier (set by --serial)" }, { "X", "X coordinate of the centroid" }, { "Y", "Y coordinate of the centroid" }, { "-", "empty column" }, { "Format tags for photometric data:", NULL }, { "M", "magnitude" }, { "m", "uncertainty in the magnitude" }, { "B", "background level" }, { "b", "background scatter" }, { "F", "flux" }, { "f", "flux uncertainty" }, { "A", "same as \"F\"" }, { "a", "same as \"f\"" }, { "E", "flux in electrons" }, { "e", "flux uncertainty in electrons" }, { "X", "X coordinate of the fitted centroid" }, { "x", "X coordinate uncertainty" }, { "Y", "Y coordinate of the fitted centroid" }, { "y", "Y coordinate uncertainty" }, { "W", "Statistical profile size (S), in pixels" }, { "D", "Statistical profile deviation parameter (D), in pixels" }, { "K", "Statistical profile deviation parameter (K), in pixels" }, { "w", "Uncertainty of statistical profile size" }, { "-", "empty column" }, { "Fine tuning of aperture photometry:", NULL }, { "-j, --disjoint-annuli, --disjoint-rings", "During the bacground determination on the aperture annuli, omit " "the pixels which belongs to the annuli of other centriods. On very " "dense fields this might make the aperture photometry impossible since " "for some or many of the target centroids, the bacground level cannot " "be derived due to the lack of sufficient number of background pixels. " }, { "-p, --disjoint-apertures", "During the bacground determination on the aperture annuli, omit " "the pixels which belongs to the apertures of other centriods. " }, { "-x, --disjoint-radius ", "During the bacground determination on the aperture annuli, omit " "the pixels which are closer to the other centroids than the " "specified radius." }, { "-k, --spline", "Use a flux-conserving biquadratic spline interpolation surface " "for photometry purposes. This surface yields some sort of weighting " "within each pixel due to the properties of the spline interpolation." }, { "-m, --magfit orders=[:[:[:]]],iterations=,sigma=", __extension__ "Perform a magnitude transformation after the photometry. Currently " "impleneted only in the case of image subtraction photometry and " "always use the reference photometry (see --input-raw-photometry) " "as a reference for magnitude transformation too. This command line " "option must be followed by the parameters of the magnitude fit, " "namely the list the of spatial polynomial orders for the " "subsequent color orders (colon-separated list), and the number of " "(optional) outlier rejection iterations and its limit in standard " "deviation (sigma) units." }, { "Photometry on subtracted/convolved images:", NULL }, { "-P, --input-raw-photometry ", "Name of the file containing the coordinate lists and the raw " "photometric information for the reference image." }, { "-K, --input-kernel ", "The kernel solution which resulted during the creation of the " "convolved and/or subtracted image. This information is also required " "for the proper self-consistent aperture photometry on subtracted images. " "Omitting this file will result an assumption for identical " "convolution transformation, which only appropriate if the subtracted " "image is created by a literal arithmetic subtraction (and not " "convolution based subtraction)." }, { "Optimal aperture determination:", NULL }, { "--output-list ", "The name of the output centroid list file, in which the radius " "of the optimal aperture is also stored. The optimal aperture is " "derived from the object flux itself, the gain level, the " "background noise and the FWHM of the objects. " "The background noise can be specified using the -d|--sky-noise " "argument (see there). The FWHM is given by the option -f|--fwhm." }, { "-d, --skynoise ", "Sky (bacground level) noise level in ADUs." }, { "-f, --fwhm ", "Full width at half magnitude (FWHM) for the stellar objects." }, { "Sky fitting parameters:", NULL }, { "mean", "Use the mean value of the pixels in the annulus as a sky value." }, { "median", "Use the median value of the pixels in the annulus as a sky value." }, { "mode", "Use the mode of the pixels in the annulus as a sky value." }, { "iterations=", "Do the specified number of iterations in order to reject outlier pixels." }, { "lower, upper, sigma=", "Lower, upper and generic (symmetric) outlier level in the units of " "standard deviations." }, { "force=", "Use the forced constant level for sky background, with zero nominal " "scatter." }, { NULL, NULL } }; int fprint_fiphot_long_help(FILE *fw,int is_wiki) { char *synopsis= "fiphot [options] [] [-o|--output ]"; char *description= "This program performs aperture photometry on normal or " "subtracted/convolved images."; fprint_generic_long_help(fw,is_wiki,fiphot_long_help,synopsis,description); return(0); } /*****************************************************************************/ int parse_gainpoly_string(char *gainstr,spatialgain *sg) { char *gs,**tokens; int i,p,o,n; gs=strdup(gainstr); tokens=tokenize_char_dyn(gs,','); for ( n=0 ; tokens[n] != NULL ; ) n++; sg->coeff=NULL; for ( o=0,p=0 ; p+o+1 <= n ; ) { sg->coeff=(double *)realloc(sg->coeff,sizeof(double)*(p+o+1)); for ( i=0 ; i<=o ; i++,p++ ) { sscanf(tokens[p],"%lg",&sg->coeff[p]); } o++; } sg->order=o-1; free(tokens); free(gs); return(0); } int get_gain_info_from_header(spatialgain *sg,fitsheaderset *header) { fitsheader *fh; double gain,vmin; if ( (fh=fits_headerset_get_header(header,"GAINPOLY",0)) != NULL && fh->vtype==FITS_VSTR ) { parse_gainpoly_string(fh->vstr,sg); } else if ( ! fits_headerset_get_as_double(header,"GAIN",&gain,!0) ) { sg->order=0; sg->coeff=(double *)malloc(sizeof(double)); sg->coeff[0]=gain; } if ( ! fits_headerset_get_as_double(header,"GAINVMIN",&vmin,!0) ) { if ( vmin>0.0 ) sg->vmin=vmin; else sg->vmin=0.0; } else sg->vmin=0.0; return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { fits *img,*refimg,*subimg; char **mask,**submask; FILE *fr; char *imgname,*inlistname,*inweightname, *outlistname,*outname,*outphotname,*inphotname; char *refname,*subname,*subkernelfile,**inmasklist, *appar,*apcolpar,*skyfitpar,*wusagepar,*magfitpar; char *oformat,*ofxy,*ofph,*nanstring,*serialstring,*maskignorestr, *gainstr; int frameno; kernellist klist; double skysigma,sigma,fwhm; magflux mf0; int i,is_help; xphotpar xpp; photstar *ps; int np; colread col; apgeom *inaps; int ninap,numap,zoom; weightlist wl_data,*wl; int weightusage; char *subpixfile; int is_normalize; magfitparams mfp; magfitstat mfs; spatialgain sg; int is_auto_gain=0; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; imgname=inlistname=outlistname=outname=NULL; subname=subkernelfile=inweightname=NULL; refname=NULL;inmasklist=NULL; outphotname=inphotname=NULL; subpixfile=NULL;is_normalize=0; wusagepar=oformat=appar=apcolpar=NULL, serialstring=NULL,nanstring="-"; magfitpar=NULL; is_verbose=is_comment=is_help=0;frameno=0; gainstr=NULL; fwhm=SIG_FWHM; skyfitpar=NULL; xpp.bgm.type=BGTYPE_MEDIAN; xpp.bgm.rejniter=2, xpp.bgm.rejlower=xpp.bgm.rejupper=2.0; xpp.maskignore=MASK_SATURATED|MASK_HOT; xpp.use_biquad=0; xpp.wconfdist=0.0; xpp.use_sky=0; xpp.sky=0.0; xpp.is_disjoint_rings=0; xpp.is_disjoint_apertures=0; xpp.disjoint_radius=-1.0; maskignorestr=NULL; mf0.magnitude=10.0, mf0.intensity=10000.0; col.colx=1,col.coly=2; col.colap=NULL; col.colid=col.colmag=col.colcol=-1; sg.vmin=0.0; zoom=1; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-i|--input:%s",&imgname, "--frame:%d",&frameno, "-o|--output:%s",&outname, "-L|--input-list:%s",&inlistname, "--output-list:%s",&outlistname, "--output-raw-photometry:%s",&outphotname, "-R|--input-raw-photometry:%s",&inphotname, "-M|--input-mask:%t",&inmasklist, "-W|--input-weight:%s",&inweightname, "-w|--weight-usage:%s",&wusagepar, "-r|--reference:%s",&refname, "-s|--input-subtracted:%s",&subname, "-K|--input-kernel:%s",&subkernelfile, "-d|--skysigma|--sky-noise|--skynoise:%g",&skysigma, "-g|--gain|--gain-poly|--gainpoly:%s",&gainstr, "--gain-vmin|--gainvmin:%g",&sg.vmin, "-f|--fwhm:%g",&fwhm, "--mag-flux:%g,%g",&mf0.magnitude,&mf0.intensity, "--sky-fit:%s",&skyfitpar, "--aperture-mask-ignore:%s",&maskignorestr, "-a|--aperture|--apertures:%s",&appar, "-j|--disjoint-rings|--disjoint-annuli:%f",&xpp.is_disjoint_rings, "-p|--disjoint-apertures:%f",&xpp.is_disjoint_apertures, "-x|--disjoint-radius:%g",&xpp.disjoint_radius, "-k|--spline:%f",&xpp.use_biquad, "-m|--magfit:%s",&magfitpar, "--col-xy:%Pd,%Pd",&col.colx,&col.coly, "--col-ap|--col-aperture|--col-apertures:%s",&apcolpar, "--col-id|--col-identifier:%Pd",&col.colid, "--col-mag|--col-magnitude:%Pd",&col.colmag, "--col-col|--col-color:%Pd",&col.colcol, "--col-err|--col-error|--col-merr|--col-magerr:%Pd",&col.colerr, "-z|--zoom:%Pd",&zoom, "-F|--format|--format-output:%s",&oformat, "--nan|--nan-format|--nan-string:%s",&nanstring, "--serial:%s",&serialstring, "-u|--input-subpixel:%s",&subpixfile, "--normalize:%f",&is_normalize, "--comment:%i",&is_comment,"(C):%i",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-:%w",&imgname, "-*|+*:%e", "*:%w",&imgname, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fiphot",FITSH_FIPHOT_VERSION,is_help); return(0); } else if ( 10 ) col.colid--; if ( col.colmag>0 ) col.colmag--; if ( col.colcol>0 ) col.colcol--; if ( gainstr != NULL && strcmp(gainstr,"auto")==0 ) { sg.order=-1; sg.coeff=NULL; sg.vmin=0.0; is_auto_gain=1; } else if ( gainstr != NULL ) { parse_gainpoly_string(gainstr,&sg); is_auto_gain=0; } else { sg.order=0; sg.coeff=(double *)malloc(sizeof(double)*1); sg.coeff[0]=1.0; sg.vmin=0.0; is_auto_gain=0; } sigma=fwhm/SIG_FWHM; col.colap=create_col_ap_data(apcolpar); if ( subkernelfile != NULL ) { fr=fopenread(subkernelfile); if ( fr==NULL ) { fprint_error("unable to open kernel file '%s'",subkernelfile); return(1); } else if ( kernel_info_read(fr,&klist) ) { fprint_error("unable to parse kernel file contents"); return(1); } kernel_init_images(&klist); fcloseread(fr); } if ( magfitpar != NULL ) { char **cmd; int i,k; double d; cmd=tokenize_char_dyn(magfitpar,','); mfp.norder=-1; mfp.niter=0; mfp.sigma=3.0; for ( i=0 ; cmd != NULL && cmd[i] != NULL ; i++ ) { if ( (k=sscanf(cmd[i],"orders=%d:%d:%d:%d", &mfp.orders[0],&mfp.orders[1], &mfp.orders[2],&mfp.orders[3])) >= 1 ) mfp.norder=k-1; else if ( sscanf(cmd[i],"niter=%d",&k)==1 ) mfp.niter=k; else if ( sscanf(cmd[i],"sigma=%lg",&d)==1 && d>0.0 ) mfp.sigma=d; else { fprint_error("invalid magnitude fit parameter near '%s'.\n",cmd[i]); return(1); } } } else { mfp.norder=-1; mfp.niter=0; mfp.sigma=0.0; } if ( inphotname != NULL && refname != NULL ) { fprint_error("invalid combination of command line options (both input raw photometry file and reference image are specified)"); return(1); } if ( inphotname != NULL && inlistname != NULL ) { fprint_error("invalid combination of command line options (both input raw photometry file and input list file are specified)"); return(1); } if ( skyfitpar != NULL ) { int is_sigma; double sigma=2.0; is_sigma=0; i=scanpar(skyfitpar,SCANPAR_DEFAULT, "mean:" SNf(BGTYPE_MEAN) ,&xpp.bgm.type, "median:"SNf(BGTYPE_MEDIAN),&xpp.bgm.type, "mode:" SNf(BGTYPE_MODE) ,&xpp.bgm.type, "iterations:%d",&xpp.bgm.rejniter, "lower:%g",&xpp.bgm.rejlower, "upper:%g",&xpp.bgm.rejupper, "sigma:%g%f",&sigma,&is_sigma, "force:%g%f",&xpp.sky,&xpp.use_sky, NULL); if ( is_sigma ) xpp.bgm.rejlower=xpp.bgm.rejupper=sigma; } if ( oformat==NULL ) { ofxy="IXY"; ofph="MmBb"; } else { ofxy=output_format_xy(oformat); ofph=output_format_ph(oformat); if ( ofxy==NULL || ofph==NULL ) { fprint_error("invalid output format specification in '%s'",oformat); return(1); } } if ( maskignorestr != NULL ) { xpp.maskignore=parse_mask_flags(maskignorestr); if ( xpp.maskignore<0 ) { fprint_error("invalid mask specification in '%s'",maskignorestr); return(1); } } /* silently ignore unexpected '--zoom' values: */ if ( zoom<1 ) zoom=1; i=create_input_ap_data(appar,&inaps,&ninap,zoom); if ( i ) { fprint_error("invalid aperture specification in '%s'",appar); return(1); } if ( inlistname==NULL && inphotname==NULL ) { fprint_error("no coordinate list has been specified"); return(1); } if ( inlistname != NULL ) { fr=fopenread(inlistname); if ( fr==NULL ) { fprint_error("unable to open input list file '%s'",inlistname); return(1); } read_input_star_list(fr,&ps,&np,&col,zoom); fcloseread(fr); i=check_apertures(ps,np); if ( i<0 ) { fprint_error("invalid aperture information in input list file"); return(1); } else if ( ninap==0 && i==0 ) { fprint_error("no aperture information has been found in input list file"); return(1); } else if ( ninap> 0 && i> 0 ) { fprint_error("ambiguous aperture specifications"); return(1); } else if ( ninap>0 ) numap=ninap; else numap=i,inaps=NULL; } else numap=0; if ( outlistname != NULL && numap != 1 ) { fprint_error("only one aperture should be specified if optimal aperture estimation is requested"); return(1); } if ( subpixfile != NULL ) { FILE *fr; int i,j; fr=fopenread(subpixfile); if ( fr==NULL ) { fprint_error("unable to open subpixel data file"); return(1); } read_subpixel_file(fr,&xpp.subpixeldata,&xpp.subg); fcloseread(fr); if ( is_normalize ) normalize_subpixeldata(xpp.subpixeldata,xpp.subg); for ( i=0 ; ii.dim != 2 ) { fprint_error("image dimension differs from 2."); return(1); } fits_rescale(img); if ( outlistname != NULL ) is_calc_opt_apert=1; else is_calc_opt_apert=0; mask=fits_mask_read_from_header(&img->header,img->i.sx,img->i.sy,NULL); if ( inmasklist != NULL ) { if ( join_masks_from_files(mask,img->i.sx,img->i.sy,inmasklist) ) { fprint_error("unable to read (one of the) mask file(s)"); return(1); } } fits_mask_mark_nans(&img->i,mask,MASK_NAN); if ( is_auto_gain ) get_gain_info_from_header(&sg,&img->header); do_photometry(&img->i,mask,ps,np,wl,weightusage,is_calc_opt_apert,inaps,numap,&sg,sigma,&xpp); fits_free(img); if ( outlistname != NULL ) { FILE *fw; fw=fopenwrite(outlistname); if ( fw==NULL ) { fprint_error("unable to create output list file '%s'",outlistname); return(1); } write_output_star_list(fw,ps,np); fclosewrite(fw); } if ( outname != NULL ) { FILE *fw; calculate_magnitudes(ps,np,&mf0); fw=fopenwrite(outname); if ( fw==NULL ) { fprint_error("unable to create output photometry file '%s'",outname); return(1); } if ( is_comment ) { fprintf(fw,"# Created by fiphot v%s (fi: %s)\n",FITSH_FIPHOT_VERSION,FITSH_VERSION); fprintf(fw,"# Invoked command:"); for ( i=0 ; ii.sx,img->i.sy); fclosewrite(fw); } if ( outphotname != NULL ) { FILE *fw; fw=fopenwrite(outphotname); if ( fw==NULL ) { fprint_error("unable to create output raw photometry file '%s'",outphotname); return(1); } write_raw_photometry(fw,ps,np,nanstring); fclosewrite(fw); } } /****************************************************************************** One reference image and one subtracted image are given: simple aperture photometry on the reference image and after it, add the all aperture photometry results of the subtracted images to the result of the photometry of the reference image. ******************************************************************************/ else if ( ( refname != NULL || inphotname != NULL ) && subname != NULL ) { kernellist *kl; char *basename; int i,sx,sy; refimg=NULL; mask=NULL; if ( refname != NULL ) { basename=fits_basename(refname,&frameno); if ( (fr=fopenread(basename))==NULL ) { fprint_error("unable to open reference image file '%s'.",basename); return(1); } fclose(fr); if ( refimg==NULL ) { fprint_error("unable to interpret reference image input as FITS data."); return(1); } if ( refimg->i.dim != 2 ) { fprint_error("reference image dimension differs from 2."); return(1); } mask=fits_mask_read_from_header(&refimg->header,refimg->i.sx,refimg->i.sy,NULL); if ( inmasklist != NULL ) { if ( join_masks_from_files(mask,refimg->i.sx,refimg->i.sy,inmasklist) ) { fprint_error("unable to read (one of the) mask file(s)"); return(1); } } logmsg(is_verbose,"Performing reference photometry ... "); if ( is_auto_gain ) get_gain_info_from_header(&sg,&refimg->header); do_photometry(&refimg->i,mask,ps,np,wl,weightusage,0,inaps,numap,&sg,sigma,&xpp); logmsg(is_verbose,"done.\n"); for ( i=0 ; inumap ) numap=ps[i].n; } } basename=fits_basename(subname,&frameno); if ( (fr=fopenread(basename))==NULL ) { fprint_error("unable to open subtracted image file '%s'.",basename); return(1); } subimg=fits_read_frame_to_image(fr,frameno); fclose(fr); if ( subimg==NULL ) { fprint_error("unable to interpret subtracted image input as FITS data."); return(1); } if ( subimg->i.dim != 2 ) { fprint_error("subtracted image dimension differs from 2."); return(1); } sx=subimg->i.sx; sy=subimg->i.sy; if ( refimg != NULL && mask != NULL ) { submask=fits_mask_duplicate(mask,refimg->i.sx,refimg->i.sy); fits_mask_mask_from_header(submask,&subimg->header,refimg->i.sx,refimg->i.sy,NULL); } else submask=fits_mask_read_from_header(&subimg->header,subimg->i.sx,subimg->i.sy,NULL); if ( subkernelfile != NULL ) kl=&klist; else kl=NULL; if ( is_auto_gain ) get_gain_info_from_header(&sg,&subimg->header); logmsg(is_verbose,"Photometry on subtracted image '%s' ... ",subname); do_subtracted_photometry(&subimg->i,submask,ps,np,inaps,ninap,&sg,&xpp,kl); logmsg(is_verbose,"done.\n"); fits_mask_free(submask); if ( refimg != NULL ) fits_free(refimg); if ( mask != NULL ) fits_mask_free(mask); if ( mfp.norder>=0 ) do_magnitude_fit(ps,np,&mfp,sx,sy,&mfs); if ( outname != NULL ) { FILE *fw; int a; calculate_magnitudes(ps,np,&mf0); fw=fopenwrite(outname); if ( fw==NULL ) { fprint_error("unable to create output photometry file '%s'",outname); return(1); } if ( is_comment ) { fprintf(fw,"# Created by fiphot v%s (fi: %s)\n",FITSH_FIPHOT_VERSION,FITSH_VERSION); fprintf(fw,"# Invoked command:"); for ( i=0 ; ii.sx,subimg->i.sy); if ( mfp.norder>=0 && is_comment ) { fprintf(fw,"# Magnitude transformation statistics - %d stars:\n",mfs.nstar); for ( a=0 ; a. */ /*****************************************************************************/ #include #include #include #include "tokenize.h" #ifdef HAVE_LIBINTL_H #include #define _(string) gettext(string) #else #define _(string) string #endif #define TOKENIZE_ABORT_ON_MALLOC #ifdef TOKENIZE_ABORT_ON_MALLOC #define realloc_check(ptr,size) \ do \ { if ( ptr==NULL && size>0 ) \ { fprintf(stderr,"tokenize.c: %s.\n",_("memory exhausted"));\ abort(); \ } \ } while(0) #else #define realloc_check(ptr,size) #endif #define malloc_check(ptr) realloc_check(ptr,1) /*****************************************************************************/ void remove_newlines_and_comments(char *buff) { int k; while ( *buff ) { if ( *buff=='#' ) *buff=0; else { for ( k=0 ; buff[k]==10 || buff[k]==13 ; ) k++; if ( k ) memmove(buff,buff+k,strlen(buff)+1-k); else buff++; } } } void remove_spaces_and_comments(char *buff) { int k; while ( *buff ) { if ( *buff=='#' ) *buff=0; else { for ( k=0 ; buff[k]==9 || buff[k]==32 || buff[k]==10 || buff[k]==13 ; ) k++; if ( k ) memmove(buff,buff+k,strlen(buff)+1-k); else buff++; } } } void remove_spaces(char *buff) { int k; while ( *buff ) { for ( k=0 ; buff[k]==9 || buff[k]==32 || buff[k]==10 || buff[k]==13 ; ) k++; if ( k ) memmove(buff,buff+k,strlen(buff)+1-k); else buff++; } } /*****************************************************************************/ void remove_quotes(char *buff) { int k; while ( *buff ) { for ( k=0 ; buff[k]=='"' ; ) k++; if ( k ) memmove(buff,buff+k,strlen(buff)+1-k); else buff++; } } /*****************************************************************************/ int char_is_space(int c) { if ( c==32 || c==13 || c==10 || c==9 ) return(1); else return(0); } /*****************************************************************************/ int tokenize_spaces(char *buff,char **tokens,int max) { int intoken,inquota,n; char **tsave; tsave=tokens; intoken=0,inquota=0;n=0; while ( *buff && n=nm-1 ) { nm+=16; rtokens=(char **)realloc(rtokens,sizeof(char *)*nm); realloc_check(rtokens,sizeof(char *)*nm); } } else if ( intoken && ( (char_is_space(*buff) && inquota) || (!char_is_space(*buff)) ) ) { if ( *buff=='"' ) inquota=!inquota; buff++; } else if ( intoken && ! inquota && char_is_space(*buff) ) { *buff=0,buff++; intoken=0; } else buff++; }; rtokens[n]=NULL; for ( i=0 ; i. */ /*****************************************************************************/ #include #include #include #include #include #ifdef HAVE_LIBINTL_H #include #define _(string) gettext(string) #else #define _(string) string #endif #include "format.h" #define FORMAT_ABORT_ON_MALLOC #ifdef FORMAT_ABORT_ON_MALLOC #define realloc_check(ptr,size) \ do \ { if ( ptr==NULL && size>0 ) \ { fprintf(stderr,"format.c: %s.\n",_("memory exhausted"));\ abort(); \ } \ } while(0) #else #define realloc_check(ptr,size) #endif #define malloc_check(ptr) realloc_check(ptr,1) /*****************************************************************************/ #define BLOCK_FORMAT 256 #define FORMAT_ABORT_ON_MALLOC /*****************************************************************************/ static int format_int_realloc(char **out,int *len,int *alen,int req) { if ( (*len)+req > (*alen) ) { req+=(*len); *alen = BLOCK_FORMAT*((req+BLOCK_FORMAT-1)/BLOCK_FORMAT); *out = realloc(*out,*alen); realloc_check(*out,*alen); } return(0); } static int format_get_parameters(char *format,int *d1,int *d2,int *fmt,char **next) { int set; set=0; while ( isspace((int)(*format)) ) format++; if ( *format && sscanf(format,"%d",d1)==1 ) { set|=1; while ( *format=='-' || isdigit((int)(*format)) ) format++; while ( isspace((int)(*format)) ) format++; } if ( *format=='.' ) format++; while ( isspace((int)(*format)) ) format++; if ( *format && sscanf(format,"%d",d2)==1 ) { set|=2; while ( *format=='-' || isdigit((int)(*format)) ) format++; while ( isspace((int)(*format)) ) format++; } if ( isalpha((int)(*format)) ) { *fmt=(int)(*format); format++; if ( next != NULL ) *next=format; return(set); } else { if ( next != NULL ) *next=format; return(-1); } } /* call: format_check_if_formatted(fmt,"..."); */ int format_check_if_formatted(char *format,char *fchars) { int fmt,d1,d2,set; char *next; while ( *format ) { if ( *format=='%' && *(format+1) ) { format++; set=format_get_parameters(format,&d1,&d2,&fmt,&next); if ( set>=0 ) format=next; else if ( *format=='%' ) format++; if ( strchr(fchars,fmt) != NULL ) return(1); } else format++; } return(0); } static int format_int_add_string(char **out,int *len,int *alen,int set,int d1,char *vs) { int slen,req; slen=strlen(vs); if ( (set & 1) && abs(d1)>slen ) req=abs(d1); else req=slen; format_int_realloc(out,len,alen,req); if ( (set & 1) && d1>slen ) { memset((*out)+(*len),32,d1-slen); strcpy((*out)+(*len)+(d1-slen),vs); *len+=req; } else if ( (set & 1) && -d1>slen ) { strcpy((*out)+(*len),vs); memset((*out)+(*len)+slen,32,(-d1)-slen); (*out)[(*len)+req]=0; *len+=req; } else { strcpy((*out)+(*len),vs); *len+=slen; } return(0); } /* call: format_replace(fmt,esc,'c1',TYPE1,value1,'c2',TYPE2,value2,...,0); */ char *format_replace(char *format,int is_escape,...) { char *out,*next; int len,alen,set,d1,d2,fmt,chr,type; va_list ap; alen=BLOCK_FORMAT; out=(char *)malloc(alen); malloc_check(out); out[0]=0; len=0; while ( *format ) { if ( is_escape && *format=='\\' ) { format++; format_int_realloc(&out,&len,&alen,1); switch ( *format ) { case 'n': out[len]='\n',len++; break; case 't': out[len]='\t',len++; break; case 'r': out[len]='\r',len++; break; case 0: out[len]='\\',len++; break; default: out[len]=*format,len++; } if ( *format ) format++; } else if ( *format=='%' && *(format+1) ) { format++; set=format_get_parameters(format,&d1,&d2,&fmt,&next); /* valid printf-like format */ if ( set>=0 ) { va_start(ap,is_escape); while ( (chr=va_arg(ap,int))>0 ) { type=va_arg(ap,int); if ( chr==fmt ) break; else { switch ( type ) { case FORMAT_DEC_INTEGER: case FORMAT_HEX_INTEGER: case FORMAT_HXC_INTEGER: case FORMAT_OCT_INTEGER: (void)va_arg(ap,int); break; case FORMAT_STRING: (void)va_arg(ap,char *); break; } } } /* valid printf-like format and found in the list */ if ( chr>0 ) { int vi; char *vs; char buff[256],sbuff[16]; switch ( type ) { case FORMAT_DEC_INTEGER: vi=va_arg(ap,int); if ( (set & 2) && d2>0 ) { if ( d2>128 ) d2=128; sprintf(sbuff,"%%.%dd",d2); sprintf(buff,sbuff,vi); } else sprintf(buff,"%d",vi); format_int_add_string(&out,&len,&alen,set,d1,buff); break; case FORMAT_HEX_INTEGER: vi=va_arg(ap,int); if ( (set & 2) && d2>0 ) { if ( d2>128 ) d2=128; sprintf(sbuff,"%%.%dx",d2); sprintf(buff,sbuff,vi); } else sprintf(buff,"%x",vi); format_int_add_string(&out,&len,&alen,set,d1,buff); break; case FORMAT_HXC_INTEGER: vi=va_arg(ap,int); if ( (set & 2) && d2>0 ) { if ( d2>128 ) d2=128; sprintf(sbuff,"%%.%dX",d2); sprintf(buff,sbuff,vi); } else sprintf(buff,"%X",vi); format_int_add_string(&out,&len,&alen,set,d1,buff); break; case FORMAT_OCT_INTEGER: vi=va_arg(ap,int); if ( (set & 2) && d2>0 ) { if ( d2>128 ) d2=128; sprintf(sbuff,"%%.%do",d2); sprintf(buff,sbuff,vi); } else sprintf(buff,"%o",vi); format_int_add_string(&out,&len,&alen,set,d1,buff); break; case FORMAT_STRING: vs=va_arg(ap,char *); if ( vs == NULL ) vs="(null)"; format_int_add_string(&out,&len,&alen,set,d1,vs); break; } format=next; } /* valid but not in the list: */ else { format--; /* go back to the percent mark */ format_int_realloc(&out,&len,&alen,next-format); memcpy(out+len,format,next-format); len+=next-format; format=next; } va_end(ap); } else if ( (*format)=='%' ) { format++; format_int_realloc(&out,&len,&alen,1); out[len]='%'; len++; } else { format_int_realloc(&out,&len,&alen,2); out[len]='%'; out[len+1]=(*format); format++; len+=2; } } else { format_int_realloc(&out,&len,&alen,1); out[len]=*format,len++; format++; } }; format_int_realloc(&out,&len,&alen,1); out[len]=0; return(out); } /*****************************************************************************/ fitsh-0.9.2/src/io/scanarg.c0000644000175000017500000004151512766533723014257 0ustar apalapal/*****************************************************************************/ /* scanarg.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for parsing command-line arguments (or other lists). */ /* (c) 2005, 2006, Pal, A. (apal@szofi.elte.hu) */ /* Version: 1.1pre3, last modified: 2006.05.23 */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in scanarg.h */ /*****************************************************************************/ #ifdef HAVE_NO_FNMATCH_H #define SCANARG_WITHOUT_FNMATCH #endif #include #include #include #include #include #ifndef SCANARG_WITHOUT_FNMATCH #include #endif #include "scanarg.h" #define MBUFF_LEN 128 #define is_flag(f,x) (f&(1<<(x-'A'))) /*****************************************************************************/ static int scanarg_get_format_element(char **rfp,int *rn,int *rf) { int is_neg,n,ret,flags; char *fp; fp=*rfp; if ( *fp == '%' ) fp++; if ( *fp == '(' ) { fp++; *rfp=fp; return((int)('(')); } flags=0; while ( 'A' <= *fp && *fp <= 'Z' ) flags=flags|(1<<(*fp-'A')),fp++; if ( *fp == '-' ) is_neg=1,fp++; else is_neg=0; n=0; while ( '0' <= *fp && *fp <= '9' ) n=n*10+(*fp-'0'),fp++; if ( is_neg ) n=-n; if ( rn != NULL ) *rn=n; while ( 'A' <= *fp && *fp <= 'Z' ) flags=flags|(1<<(*fp-'A')),fp++; if ( rf != NULL ) *rf=flags; if ( ! isalpha((int)*fp) ) return(-1); ret=*fp; fp++; *rfp=fp; return(ret); } static int scanarg_is_sep(int t) { if ( t==',' || t==';' || t==':' ) return(1); else return(0); } static int scanarg_format_argnum(int fc) { switch ( fc ) { case 'e': case 'q': case 'c': return(0); case 'd': case 'g': case 's': case 'm': case 'r': case 'w': case 'a': case 't': case 'l': case 'f': case 'i': case '(': return(1); default: return(-1); } } static int matchcmp(char *pattern,char *buff) { int l; if ( pattern==NULL || pattern[0]==0 ) return(1); l=strlen(pattern); if ( pattern[l-1]=='*' ) { while ( l>0 && pattern[l-1]=='*' ) l--; if ( memcmp(buff,pattern,l)==0 ) return(0); else return(1); } else if ( strcmp(buff,pattern)==0 ) return(0); else return(1); } static int scanarg_check_integer(int farg,int ival) { int is_ok; if ( ! ( is_flag(farg,'P') || is_flag(farg,'Z') || is_flag(farg,'N') ) ) return(0); /* no constraints have been set: ival can be anything*/ is_ok=0; if ( is_flag(farg,'P') && ival> 0 ) is_ok=1; if ( is_flag(farg,'Z') && ival==0 ) is_ok=1; if ( is_flag(farg,'N') && ival< 0 ) is_ok=1; if ( is_ok ) return(0); else return(1); } int scanarg(int argc,char **argv,int flags,...) { char *fp,*wp,*mp,*carg,*aptr; char mbuff[MBUFF_LEN],flagmask[128]; int a,i,l,m,len,is_matched,argdone,morearg; int is_first,is_scan_sep,is_dd_exp,is_only_flag,is_flag_allowed; va_list ap; if ( ! ( flags & SCANARG_NO_SKIP_FIRST ) ) /* skip argv[0], if desired */ { argv++; argc--; } argdone=1;is_dd_exp=0; memset(flagmask,0,128); va_start(ap,flags); while ( 1 ) { aptr=va_arg(ap,char *); if ( aptr==NULL ) break; fp=aptr; while ( *fp && *fp != ':' ) { if ( fp[0]=='(' && isalnum((int)fp[1]) && fp[2]==')' ) { if ( ! (flags&SCANARG_ALLOW_FLAGS) ) return(-10); else { i=fp[1]; flagmask[i]=1; fp+=3; } } while ( *fp && *fp != ':' && *fp != '|' ) fp++; if ( *fp=='|' ) fp++; }; while ( *fp ) { if ( *fp=='%' ) { int fc,fn; fc=scanarg_get_format_element(&fp,NULL,NULL); if ( fc<0 ) return(-2); fn=scanarg_format_argnum(fc); if ( fn<0 ) return(-2); for ( ; fn>0 ; fn-- ) (void)va_arg(ap,void *); } else fp++; }; } va_end(ap); is_only_flag=0; while ( argc>0 ) { if ( ( flags & SCANARG_DASHDASH_EXP ) && strcmp(*argv,"--")==0 ) { argc--,argdone++; argv++; is_dd_exp=1; continue; } va_start(ap,flags); is_matched=0; if ( (*argv)[0]=='-' && (flags&SCANARG_ALLOW_FLAGS) && is_only_flag==0 && (!is_dd_exp) ) { for ( i=1,m=1 ; (*argv)[i] && m ; i++ ) { l=(*argv)[i]; if ( ! isalnum((int)l) ) m=0; else if ( ! flagmask[l] ) m=0; } if ( m && i>1 ) is_only_flag=1; } while ( ! is_matched ) { aptr=va_arg(ap,char *); if ( aptr==NULL ) break; fp=aptr; wp=fp;len=0; while ( *wp && *wp != ':' ) wp++,len++; if ( *wp != ':' ) return(-1); wp=fp;l=0; while ( lMBUFF_LEN-1 ) i=MBUFF_LEN-1; memcpy(mbuff,mp,i);mbuff[i]=0; if ( is_dd_exp ) /* if desired, after a `--' all args are going to be matched by only '*' */ { if ( strcmp(mbuff,"*")==0 ) is_matched=1; } else if ( is_only_flag>0 ) { if ( mbuff[0]=='(' && mbuff[2]==')' ) { if ( (*argv)[is_only_flag]==mbuff[1] ) { is_matched=1, is_only_flag++; } } } else { if ( strcmp(mbuff,"*")==0 ) { if ( flags & SCANARG_WILDCARD_DASH ) is_matched=1; else if ( (*argv)[0] != '-' ) is_matched=1; } else { #ifdef SCANARG_WITHOUT_FNMATCH if ( ! matchcmp(mbuff,*argv) ) is_matched=1; #else if ( flags & SCANARG_USE_STRCMP ) { if ( ! matchcmp(mbuff,*argv) ) is_matched=1; } else { if ( ! fnmatch(mbuff,*argv,0) ) is_matched=1; } #endif } } if ( *wp=='|' && ! is_matched ) wp++,l++; }; fp=fp+len+1; if ( is_matched ) break; else { int fc,fn; while ( *fp ) { if ( *fp=='%' ) { fc=scanarg_get_format_element(&fp, NULL,NULL); if ( fc<0 ) return(-2); fn=scanarg_format_argnum(fc); if ( fn<0 ) return(-2); for ( ; fn>0 ; fn-- ) (void)va_arg(ap,void *); } else fp++; }; } }; if ( ! is_matched ) return(argdone); a=0;carg=argv[1]; is_first=1;is_scan_sep=is_flag_allowed=0; while ( *fp ) { while ( *fp==32 ) fp++; if ( *fp == '%' ) { int fc,fn,narg,farg,ival,is_brk,is_static,*ipnt; double dval; char *pval,**ppval,**lval,***plval,*constr; narg=farg=0; fc=scanarg_get_format_element(&fp,&narg,&farg); if ( fc<0 ) return(-2); fn=scanarg_format_argnum(fc); if ( fn<0 ) return(-2); switch ( fc ) { case 'e': /* error */ return(argdone); break; case 'q': /* quit, stop scan */ return(0); break; case 'c': /* continue */ break; case 'd': /* -d */ if ( is_first ) a++,carg=argv[a],is_first=0; if ( argc */ if ( is_first ) a++,carg=argv[a],is_first=0; if ( argc */ if ( is_first ) a++,carg=argv[a],is_first=0; if ( argc */ if ( is_first ) a++,carg=argv[a],is_first=0; if ( argc A,B */ if ( fc=='r' ) { if ( is_first ) a++, carg=argv[a], is_first=0; if ( argc1 ) return(-8); if ( pval==NULL ) { len=strlen(carg); pval=(char *)malloc(len+1); strcpy(pval,carg); } else if ( constr != NULL ) { len=strlen(pval)+strlen(carg); len+=strlen(constr); pval=(char *)realloc(pval,len+1); strcat(pval,constr); strcat(pval,carg); } else { len=strlen(pval)+strlen(carg); pval=(char *)realloc(pval,len+1); strcat(pval,carg); } *ppval=pval; is_scan_sep=0; break; case 'w': /* */ *(va_arg(ap,char **))=argv[0]; is_scan_sep=0; break; case 'l': /* ... */ plval=va_arg(ap,char ***); lval=*plval; if ( is_flag(farg,'D') && is_flag(farg,'S') ) return(-7); else if ( is_flag(farg,'D') ) is_static=0; else if ( is_flag(farg,'S') ) is_static=1; else is_static=(flags&SCANARG_STATIC_LISTS); if ( is_static ) { if ( lval==NULL ) return(-7); for ( l=0 ; lval[l] != NULL ; ) l++; lval[l]=argv[0]; lval[l+1]=NULL; } else if ( lval==NULL ) { lval=(char **)malloc(2*sizeof(char *)); lval[0]=argv[0]; lval[1]=NULL; } else { for ( l=0 ; lval[l] != NULL ; ) l++; if ( narg<=0 || ( narg>0 && l0 && l0 && l0 ) return(-8); else if ( scanarg_is_sep(*fp) && is_scan_sep ) { while ( *fp != *carg && *carg ) carg++; if ( *fp != *carg ) return(argdone); else carg++; fp++; } else if ( scanarg_is_sep(*fp) && ! is_scan_sep ) return(-4); else if ( *fp==' ' ) { is_first=1; fp++; } else if ( *fp && *fp != '%' ) /* unexpected char */ return(-5); }; if ( is_only_flag==0 || (*argv)[is_only_flag]==0 ) { a++; argdone+=a; argv+=a; argc-=a; is_only_flag=0; } va_end(ap); }; return(0); } /*****************************************************************************/ #define scanpar_get_format_element(fp,n,f) scanarg_get_format_element(fp,n,f) static int scanpar_is_sep(int t) { if ( t==',' ) return(1); else return(0); } static int scanpar_format_argnum(int fc) { switch ( fc ) { case 'e': case 'q': case 'c': return(0); case 'd': case 'g': case 's': case 'm': case 'f': return(1); default: return(-1); } } int scanpar(char *par,int flags,...) { va_list ap; char *aptr,*fp,*wp,*mp,*aparpnt; char mbuff[MBUFF_LEN],wpar[MBUFF_LEN],apar[MBUFF_LEN]; int len,l,i,argdone,is_matched; argdone=1; while ( *par ) { wp=par;i=0; while ( *wp && *wp != '=' && (! scanpar_is_sep(*wp)) && iMBUFF_LEN-1 ) i=MBUFF_LEN-1; memcpy(mbuff,mp,i);mbuff[i]=0; if ( strcmp(mbuff,"*")==0 ) is_matched=1; else { #ifdef SCANARG_WITHOUT_FNMATCH if ( ! matchcmp(mbuff,wpar) ) is_matched=1; #else if ( flags & SCANPAR_USE_STRCMP ) { if ( ! matchcmp(mbuff,wpar) ) is_matched=1; } else { if ( ! fnmatch(mbuff,wpar,0) ) is_matched=1; } #endif } if ( *wp=='|' && ! is_matched ) wp++,l++; }; fp=fp+len+1; if ( is_matched ) break; else { int fc,fn; while ( *fp ) { if ( *fp=='%' ) { fc=scanpar_get_format_element(&fp, NULL,NULL); if ( fc<0 ) return(-2); fn=scanpar_format_argnum(fc); if ( fn<0 ) return(-2); for ( ; fn>0 ; fn-- ) (void)va_arg(ap,void *); } else fp++; }; } }; if ( ! is_matched ) return(argdone); while ( *fp ) { while ( *fp==32 || *fp==9 ) fp++; if ( *fp == '%' ) { int fc,fn,narg,farg,ival,*ipnt; double dval; char *pval; narg=0; fc=scanpar_get_format_element(&fp,&narg,&farg); if ( fc<0 ) return(-2); fn=scanpar_format_argnum(fc); if ( fn<0 ) return(-2); switch ( fc ) { case 'e': /* error */ return(argdone); break; case 'q': /* quit, stop scan */ return(0); break; case 'c': /* continue */ break; case 'd': if ( sscanf(apar,"%d",&ival)<1 ) return(argdone); if ( scanarg_check_integer(farg,ival) ) return(argdone); *(va_arg(ap,int *))=ival; break; case 'g': if ( sscanf(apar,"%lg",&dval)<1 ) return(argdone); *(va_arg(ap,double *))=dval; break; case 'm': if ( aparpnt==NULL ) pval=NULL; else { pval=(char *)malloc(strlen(apar)+1); strcpy(pval,apar); } *(va_arg(ap,char **))=pval; break; case 's': *(va_arg(ap,char **))=aparpnt; break; case 'f': ipnt=va_arg(ap,int *); if ( is_flag(farg,'N') ) l=narg; else l=1<>1) ); } /*****************************************************************************/ fitsh-0.9.2/src/io/iof.h0000644000175000017500000000567011103146655013411 0ustar apalapal/*****************************************************************************/ /* iof.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Tools for high-level file manipulation (I/O with f*() functions). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Copyright (C) 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This library 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 the program. If not, see . */ /*****************************************************************************/ #ifndef __IOF_H_INCLUDED #define __IOF_H_INCLUDED 1 /* freadline(): Reads one line (terminated by EOL, 012) from the stream 'fr' and stores it in a newly allocated string which is returned by the function. If the file stream is over, the function returns NULL. The returned string is zero-terminated and if the line read was not the last one, it includes the trailing EOL character. The string returned can be released with free(). */ char * freadline(FILE *fr); /* freadline_bs(): Reads one or more lines from the stream 'fr', and concates them if the ending is a backslash-EOL ("\\\n", 0114 0012) character pair. The function returns a pointer pointing to the newly allocated string with the line read. This string is zero-terminated, includes the last trailing EOL character and all internal backslash-EOLs are removed. The string returned can be released with free(). */ char * freadline_bs(FILE *fr); /* fopenread(), fopenwrite(): Opens the file 'name' for reading or writing in binary mode. If the name was "-" or NULL, the functions return stdin or stdout respectively. */ FILE * fopenread(char *name); FILE * fopenwrite(char *name); /* fcloseread(), fclosewrite(): Clses the stream 'fr' if it is not stdin or stdout. Can be used with the functions fopenread()/fopenwrite(). */ int fcloseread(FILE *fr); int fclosewrite(FILE *fw); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/io/scanarg.h0000644000175000017500000001031410667340122014240 0ustar apalapal/*****************************************************************************/ /* scanarg.h */ /*****************************************************************************/ #ifndef __SCANARG_H_INCLUDED #define __SCANARG_H_INCLUDED 1 #define SCANARG_DEFAULT 0x00 #define SCANARG_DASHDASH_ARG 0x01 #define SCANARG_DASHDASH_EXP 0x02 #define SCANARG_DASHDASH (SCANARG_DASHDASH_EXP|SCANARG_DASHDASH_ARG) #define SCANARG_WILDCARD_DASH 0x04 #define SCANARG_NO_SKIP_FIRST 0x08 #define SCANARG_DYNAMIC_LISTS 0x00 /* this is the default for %l and %t */ #define SCANARG_STATIC_LISTS 0x10 #define SCANARG_USE_STRCMP 0x20 #define SCANARG_ALLOW_FLAGS 0x40 #define SNf(i) SNf_str(i) #define SNf_str(i) "%SN" #i "f" /* scanarg(): Scans the (basically) command-line argument list (*argc,argv[]) by the rules listed in 'format's. The results are stored in the variables listed after the format string, like the scanf()-like functions. All patterns to be matched should be separated by the (list of) pointer(s) where the result(s) are going to be stored. */ int scanarg(int argc,char **argv,int flags,...); /****************************************************************************** The syntax of the 'format' strings: arg[|arg2[|...]]:{%[][e|q|d|g|s|m|r|w|l|t|f|i|(...)]} Here 'arg' can be any fnmatch-like expression or a string like '(x)' if SCANARG_ALLOW_FLAGS is set. %e: Error (stops argument scan processing and returns an error). %q: Quit (stops argument processing and returns successfully). %c: Continue (do nothing). %[PZN]d: Integer. P allows positive, Z allows zero and N allows negative number. If none of them are specified, all integer values are accepted. For example, to accept only natural (non-negative integer) numbers, write "%PZd". %g: Real (stored as double) %s: String (save the pointer of the argument) %m: String (duplicates the argument with malloc() and save this pointer) %[{C|S|M|L}}r: String. (concates after the dynamical string, separate the strings optionally with comma[C], whitespace[S], semicolon[M], colon[L] or without any separator[simply %r]) %w: The switch as a string. (save the pointer of the switch) %[{C|S|M|L}}a: The switch as a string. (concates after the dynamical string, separate the strings optionally with comma[C], whitespace[S], semicolon[M], colon[L] or without any separator[simply %a]) %[{D|S[]}]l: List of the matched arguments. (D: dynamic, S: static with maximum elements.) %[{D|S[]}][M]t: List of the arguments of the switch. (D: dynamic, S: static with maximum elements, M: more than one argument after the swith is accepted, until another switch...) %[N][S][f]: Flag. (N: threat as a number otherwise a bit index - then 0 is the LSB, S: set the value instead of or'ing) %[]i: Incrementation (by ). %([,[,...]]): Selection. Examples: Usage: prog [-n|--number ] [-k] [-o|--output ] => scanarg(argc,argv,0, "-n|--number:%d",&n, "-k:%f",&k_flag, "-o|--output:%s",&outputname, NULL); Usage: prog [-i ] [-x :] [-y :] [-o ] => char **list=NULL; scanarg(argc,argv,0, "-i:%Dl",&list, "-x:%g:%g",&xmin,&xmax, "-y:%g:%g",&ymin,&ymax, "-o:%s",&outputname, NULL); Usage: prog [-l [,]] [-l ,...] [...] [-v|--verbose] [--opt-*] [-m|--method {alpha|betha|gamma}] => char *explist=NULL,**opt_args=NULL; int verbose_level=0,method=-1; scanarg(argc,argv,0, "-l:%Cr",&explist, "-v|--verbose:%1i",&verbose_level, "--opt-*:%t",&opt_args, "-m|--method:%(alpha,beta,gamma)",&method, NULL); ******************************************************************************/ #define SCANPAR_DEFAULT 0x00 #define SCANPAR_USE_STRCMP 0x20 int scanpar(char *par,int flags,...); /*****************************************************************************/ #define SCANFLAG_DEFAULT 0x00 #define SCANFLAG_ALLOW_NEGATE 0x01 #define SCANFLAG_ALLOW_RESET 0x02 int scanflag(char *par,int flags,...); /*****************************************************************************/ #endif fitsh-0.9.2/src/io/tokenize.h0000644000175000017500000000764011103146230014450 0ustar apalapal/*****************************************************************************/ /* tokenize.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for basic text processing. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Copyright (C) 2001, 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This library 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 the program. If not, see . */ /*****************************************************************************/ #ifndef __TOKENIZE_H_INCLUDED #define __TOKENIZE_H_INCLUDED 1 /*****************************************************************************/ /* remove_newlines_and_comments(): Removes newlines (012 and 015) and comments (all data after a #) from the string 'buff'. */ void remove_newlines_and_comments(char *buff); /* remove_spaces_and_comments(): Removes whitespaces (011, 012, 015 and 040) and comments from the string 'buff'. */ void remove_spaces_and_comments(char *buff); /* remove_spaces(): Removes whitespaces (011, 012, 015 and 040) from the string 'buff'. */ void remove_spaces(char *buff); /* remove_quote(): Removes all double quotation marks (042) from the string 'buff'. */ void remove_quotes(char *buff); /* char_is_space(): Returns a nonzero value if 'c' is a whitespace character, otherwise 0. */ int char_is_space(int c); /* tokenize_spaces(): Tokenizes the string 'buff', where tokens are delimited by one or more whitespaces. The string 'buff' are modified and the pointers in the array 'tokens' will point to the tokens stored in the newly modified string. After each token, a trailing zero (000) are put. The number of tokens are maximalized by the argument 'max'. The function returns the number of tokens and the last element of the array 'tokens' is set to NULL: tokens[max]==NULL (so, note that the array 'tokens' should be declared somehow like char *tokens[max+1]). All parts of buff are treated as one token if it is put between double quotation marks (042) and after the whole process, the quotation marks are removed (from the begining and the end of the tokens). */ int tokenize_spaces(char *buff,char **tokens,int max); char ** tokenize_spaces_dyn(char *buff); /* tokenize_char(): Tokenizes the string 'buff', where tokens are delimited by a single character given in the argument 'tchar'. There's no effect of double- quotation marks, spaces or any other special characters. The string 'buff' is modified and the pointers in the array 'tokens' point to the tokens in the newly modified string. After each token, a trailing zero (000) are put. The number of tokens are maximalized by the argument 'max'. */ int tokenize_char(char *buff,char **tokens,int tchar,int max); char ** tokenize_char_dyn_wwt(char *buff,int tchar,int is_terminate); char ** tokenize_char_dyn(char *buff,int tchar); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/io/Makefile.in0000644000175000017500000000060411657564434014535 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ CFLAGS=@CFLAGS@ all: iof.o tokenize.o scanarg.o format.o .PHONY: all clean iof.o: iof.c iof.h $(CC) $(CFLAGS) -c iof.c scanarg.o: scanarg.c scanarg.h $(CC) $(CFLAGS) -c scanarg.c tokenize.o: tokenize.c tokenize.h $(CC) $(CFLAGS) -c tokenize.c format.o: format.c format.h $(CC) $(CFLAGS) -c format.c clean: rm -f *.o *.a fitsh-0.9.2/src/io/format.h0000644000175000017500000000437411237103144014116 0ustar apalapal/*****************************************************************************/ /* format.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Simple *printf()-like implementation for arbitrary string formatting */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Copyright (C) 2007; Pal, A. (apal@szofi.elte.hu) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This library 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 the program. If not, see . */ /*****************************************************************************/ #ifndef __FORMAT_H_INCLUDED #define __FORMAT_H_INCLUDED 1 /*****************************************************************************/ #define FORMAT_STRING 0x01 #define FORMAT_OCT_INTEGER 0x11 #define FORMAT_DEC_INTEGER 0x12 #define FORMAT_HEX_INTEGER 0x13 #define FORMAT_HXC_INTEGER 0x14 #define FORMAT_INTEGER FORMAT_DEC_INTEGER /*****************************************************************************/ /* call: format_check_if_formatted(fmt,"..."); */ int format_check_if_formatted(char *format,char *fchars); /* call: format_replace(fmt,esc,'c1',TYPE1,value1,'c2',TYPE2,value2,...,0); */ char * format_replace(char *format,int is_escape,...); /*****************************************************************************/ #endif /* #ifndef __FORMAT_H_INCLUDED */ /*****************************************************************************/ fitsh-0.9.2/src/io/iof.c0000644000175000017500000000702011104653037013371 0ustar apalapal/*****************************************************************************/ /* iof.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Tools for high-level file manipulation (I/O with f*() functions). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in iof.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Copyright (C) 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This library 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 the program. If not, see . */ /*****************************************************************************/ #include #include #include #ifdef HAVE_LIBINTL_H #include #define _(string) gettext(string) #else #define _(string) string #endif #include "iof.h" #define IOF_ABORT_ON_MALLOC #ifdef IOF_ABORT_ON_MALLOC #define realloc_check(ptr,size) \ do \ { if ( ptr==NULL && size>0 ) \ { fprintf(stderr,"iof.c: %s.\n",_("memory exhausted"));\ abort(); \ } \ } while(0) #else #define realloc_check(ptr,size) #endif #define malloc_check(ptr) realloc_check(ptr,1) /*****************************************************************************/ char *freadline(FILE *fr) { char *ret,buff[256]; ret=NULL; if ( feof(fr) ) return(NULL); while ( 1 ) { if ( fgets(buff,255,fr)==NULL ) break; if ( ret==NULL ) ret=(char *)malloc(strlen(buff)+1),ret[0]=0; else ret=(char *)realloc(ret,strlen(ret)+strlen(buff)+1); malloc_check(ret); strcat(ret,buff); if ( ret[strlen(ret)-1]==10 ) break; } return(ret); } char *freadline_bs(FILE *fr) { char *ret,*wr; int n; ret=NULL; while ( 1 ) { wr=freadline(fr); if ( wr==NULL ) return(ret); else { if ( ret==NULL ) ret=wr; else { ret=realloc(ret,strlen(ret)+strlen(wr)+1); malloc_check(ret); strcat(ret,wr); free(wr); } n=strlen(ret); if ( n>=2 ) { if ( ret[n-1]==0x0A && ret[n-2]=='\\' ) ret[n-2]=0; else return(ret); } else return(ret); } }; return(NULL); } /*****************************************************************************/ FILE *fopenread(char *name) { FILE *fr; if ( name==NULL ) fr=stdin; else if ( strcmp(name,"-")==0 ) fr=stdin; else fr=fopen(name,"rb"); return(fr); } FILE *fopenwrite(char *name) { FILE *fw; if ( name==NULL ) fw=stdout; else if ( strcmp(name,"-")==0 ) fw=stdout; else fw=fopen(name,"wb"); return(fw); } int fcloseread(FILE *fr) { if ( fileno(fr) != fileno(stdin) ) fclose(fr); return(0); } int fclosewrite(FILE *fw) { if ( fileno(fw) != fileno(stdout) ) fclose(fw); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/fiphot.h0000644000175000017500000000713212766337307013525 0ustar apalapal/*****************************************************************************/ /* fiphot.h */ /*****************************************************************************/ #ifndef __FIPHOT_H_INCLUDED #define __FIPHOT_H_INCLUDED 1 #include "apphot.h" /* typedef: bgmode */ /*****************************************************************************/ #define USE_WEIGHT_SUBTRACTED 1 #define USE_WEIGHT_WEIGHTED 2 /*****************************************************************************/ #define APGEOM_TYPE_CIRCULAR 1 #define APGEOM_TYPE_POLYGON 2 typedef struct { int apgeom_type; double r0,ra,da; double *r0_poly,*ra_poly,*da_poly; int nr0,nra,nda; } apgeom; typedef struct { apgeom ag; double bgarea,bgflux,bgmedian,bgsigma; double flux,fluxerr; double cntr_x,cntr_x_err, cntr_y,cntr_y_err, cntr_width,cntr_w_err,cntr_w_d,cntr_w_k; double mag ,magerr ; int flag,rtot,rbad,rign,atot,abad; } photflux; typedef struct { double x,y; apgeom *inaps; int ninap; int n; photflux *fluxes; /* size == n */ apgeom optimal; photflux *rfflux; /* size == n */ /* these are read from the raw pho- */ /* tometry file */ int use_ref; /* use a reference magnitude? */ double ref_mag; /* reference magnitude for imgsub */ double ref_col; /* reference color for postmagfit */ double ref_err; /* reference magnitude error */ char *id; } photstar; typedef struct { int colx,coly; int colid,colmag,colcol,colerr; int *colap; } colread; typedef struct { bgmode bgm; int maskignore; int use_biquad; double wconfdist; double sky; int use_sky; int is_disjoint_rings; int is_disjoint_apertures; double disjoint_radius; double **subpixeldata; int subg; } xphotpar; typedef struct { int orders[4]; /* spatial orders */ int norder; /* order in the color */ int niter; /* number of iterations */ double sigma; /* rejection limit in sigma */ } magfitparams; typedef struct { int nstar; /* total number of stars */ int naperture; /* total number of apertures used */ int *ninit; /* number of initially used stars */ int *nrejs; /* number of rejected stars */ } magfitstat; typedef struct { int order; /* spatial order of gain variations */ double *coeff; /* gain variation coefficients, B(order+2,2) */ double vmin; /* minimal value of the gain */ } spatialgain; /*****************************************************************************/ extern int is_comment,is_verbose; /*****************************************************************************/ int read_input_star_list(FILE *fr,photstar **rps,int *rnp,colread *col,int zoom); int read_raw_photometry(FILE *fr,photstar **rps,int *rnp); int get_id_format_parameters(photstar *ps,int np,int *rid_len,char *idf,char *ndf); int write_output_star_list(FILE *fw,photstar *ps,int np); int photometry_status(char *buff,photflux *pf); int write_photometry(FILE *fw,photstar *ps,int np,char *ofxy,char *ofph,spatialgain *sg,char *nanstring,char *serialstring,int sx,int sy); int write_raw_photometry(FILE *fw,photstar *ps,int np,char *nanstring); char * output_format_xy(char *oformat); char * output_format_ph(char *oformat); char * subtracted_format_xy(char *sformat); char * subtracted_format_ph(char *sformat); int * create_col_ap_data(char *apcolpar); int create_input_ap_data(char *appar,apgeom **rinaps,int *rninap,int zoom); int check_apertures(photstar *ps,int np); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/ficalib.c0000644000175000017500000014603212771247674013626 0ustar apalapal/*****************************************************************************/ /* ficalib.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line tool for calibrating astronomical images. */ /*****************************************************************************/ #define FITSH_FICALIB_VERSION "0.9" /*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "fitsh.h" #include "fitsmask.h" #include "statistics.h" #include "io/iof.h" #include "io/scanarg.h" #include "combine.h" #include "tensor.h" #include "common.h" #include "history.h" #include "str.h" #include "math/spline/spline.h" #include "math/fit/lmfit.h" #include "fbase.h" #include "math/splinefit.h" #include "math/polyfit.h" #include "io/tokenize.h" #include "longhelp.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int fprint_ficalib_usage(FILE *fw) { fprintf(fw, "Usage:\tficalib [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[-C|--comment] [-V|--verbose]\n"); fprintf(fw, "Main calibration master images and input/output specification:\n" "\t[-B|--input-master-bias ]\n" "\t[-D|--input-master-dark ]\n" "\t[-F|--input-master-flat ]\n" "\t[-i|--input [...] \n" "\t-r|--rewrite-output-name '[|]'\n" "\t-o|--output [...] [--[no-]clobber]\n"); fprintf(fw, "\t[-b|--bitpix ] [-M|--input-mask ]\n" "\t[--data bitpix=,bscale=,bzero=|]\n"); fprintf(fw, "Overscan correction:\n" "\t[--overscan area=:::,{spline|polynomial},order=,\n" "\t\titerations=,sigma=]\n"); fprintf(fw, "Saturation levels and leaking:\n" "\t[-s|--saturation ]\n" "\t[--leak-{left-right|lower-upper|any}|--lr|--lu|--an]\n"); fprintf(fw, "Trimming:\n" "\t[--image ::: [--trim|--no-trim]]\n"); fprintf(fw, "More fine-tunings: scaling, exposure time corrections, ...:\n" "\t[--post-scale | --post-multiply ]\n" "\t[-g|--gain ] [--gain-order ]\n" "\t[--[no-]exptime-correction]\n"); fprintf(fw, "Mosaic images:\n" "\t[--mosaic size=(,), \n" "\t ( name=,offset=(,),image=(),\n" "\t [overscan=()[,overscan=(...)]] ),\n" "\t ( name=,offset=(,),image=(),\n" "\t [overscan=()[,overscan=(...)]] ),\n" "\t ( [...] ) , ... ]\n"); fprintf(fw, "Other corrections:\n" "\t[--horizontal-stripe-removal]\n"); fprintf(fw, "FITS header keywords (for automatic processing):\n" "\t[--header exptime=,date=,time=,jd=,hjd=,jy=,hjy=\n" "\t\tgain=,gainpoly=,gainvmin=,extname=]\n" "\t[--no-history]\n"); fprintf(fw, "Default headers: exptime=EXPTIME,date=DATE-OBS,time=TIME-OBS,\n" "\t\tjd=JD,hjd=HJD,jy=JY,hjy=HJY,\n" "\t\tgain=GAIN,gainpoly=GAINPOLY,gainvmin=GAINVMIN,extname=EXTNAME\n"); return(0); } longhelp_entry ficalib_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-i, --input ", "List of input images (up to the next option)." }, { "-o, --output ", "List of output images (up to the next option)." }, { "-r, --rewrite-output-name '[|]'", __extension__ "Rewrite the output file names according to the rule specified by " "the argument of this switch. The part must contain a single " "asterix (*) that is replaced by the original file name or, " "if the part is specified and it can be matched by the " "filename, the appropriate part of the filename is written to " "the output filename. For instance, '*.fits|*.calib.fits' will " "replace the `fits` extension to `calib.fits` if the original " "filename has a fits extension, otherwise, concatenates the " "`calib.fits` as an extension to the filename. Note that the " "and part must be separated by a vertical bar (the character " "used in UNIX shells for creating pipes), therefore either " "this character must be escaped or put into quotation marks " "(according to the current shell). " "If the -o|--output list of filenames are not, but this " "argument is specified, the list of original output files will be " "the same as the list of input filenames. " }, { "Generic calibration options:", NULL }, { "--overscan ", "Specifications for overscan corrections (see also \"Overscan " "correction parameters\" below)." }, { "--mosaic size=(,),(),...", "Mosaic image topology specfications (see also \"Mosaic specification " "parameters\" below)." }, { "-M, --input-mask ", "Input mask file to co-add to output image." }, { "-B, --input-master-bias ", "Master bias image (if any)." }, { "-D, --input-master-dark ", "Master dark image (if any)." }, { "-F, --input-master-flat ", "Master flat field image (if any)." }, { "-s, --saturation ", "Saturation level." }, { "--leak-left-right, --leak-lower-upper, --leak-any", "Pixel/readout \"blooming\" direction." }, { "-g, --gain ", "Nominal gain value." }, { "--gain-order ", "Spatial polynomial order to describe gain variations." }, { "--exptime-correction", "Do exposure time correction during dark subtraction." }, { "--no-exptime-correction", "Don't do any exposure time correction for darks." }, { "--no-clobber", "Don't overwrite existing calibrated images." }, { "Output postprocessing and pixel depts:", NULL }, { "--image :::", "Final image area." }, { "--trim", "Trim output to final image area." }, { "--no-trim", "Don't trim output to final image area (default)." }, { "--post-scale ", "Scale output to have the specified mean value." }, { "--post-multiply ", "Multiply output image by the given factor." }, { "--data ", "Output pixel data format specification." }, { "-b, --bitpix ", "Standard FITS output bitpix value." }, { "Overscan correction parameters:", NULL }, { "area=:::", "Overscan area." }, { "spline", "Use cubic splines for overscan modelling." }, { "polynomial", "Use polynomials for overscan modelling." }, { "order=", "Order for overscan variation (zero: constant)." }, { "iterations=", "Number of iterations for rejecting overscan outliers." }, { "sigma=", "Overscan outlier limit in units of stddev." }, { "Other corrections:", NULL }, { "--horizontal-stripe-removal", "Remove horizontal stripes." }, { "Mosaic specification parameters:", NULL }, { "size=(,)", "Vertical and horizontal dimensions of the final image." }, { "name=", "FITS extenison name of the given mosaic section." }, { "offset=(,)", "Offset of the given mosaic section in the final image." }, { "image=(:::)", "Trim area of the given mosaic section." }, { "overscan=()", "Overscan parameters for the given mosaic section, in the same " "syntax and format as used after \"--overscan\"." }, { NULL,NULL }, }; int fprint_ficalib_long_help(FILE *fw,int is_wiki) { char *synopsis= "ficalib [options] [-i|--input ] [-o|--output ]"; char *description= "The purpose of this program is to do various calibration steps on the input " "images, including mosaic frame joining, generic overscan corrections, " "bias and (exp. time scaled) dark subtraction and flat field corrections."; fprint_generic_long_help(fw,is_wiki,ficalib_long_help,synopsis,description); return(0); } /*****************************************************************************/ #define OVERSCAN_NONE 0 #define OVERSCAN_SPLINE 1 #define OVERSCAN_POLY 2 typedef struct { int x0,y0; int sx,sy; } trim; typedef struct { trim area; int type,order; int niter; double sigma; } overscan; typedef struct { trim image; overscan *overscans; int noverscan; } geometry; typedef struct { char name[16]; geometry g; int x0,y0; } section; typedef struct { int sx,sy; section *sections; int nsection; } mosaic; typedef struct { int sx,sy; char **mask; char **inmasklist; int is_trim; int is_exptime_correction; int is_calc_gainpoly; int is_combined_dark; double saturation; double postscale,postmultiply; int reset_method; int is_remove_horizontal_stripes; int argc; char **argv; char *inputbias; char *inputdark; char *inputflat; double gain; int gainorder; double *flatpoly; double flatresd; double flatvmin; } calibdata; typedef struct { char *exptime; char *date,*time; char *gain,*gainpoly,*gainvmin; char *jd,*hjd,*jy,*hjy; char *extname; } headername; /*****************************************************************************/ void srand_auto() { int fd; unsigned int seed; fd=open("/dev/urandom",O_RDONLY); if ( fd>=0 ) { (void)read(fd,&seed,sizeof(seed)); close(fd); } else seed=time(NULL)*65536+getpid(); srand(seed); } int mkstemp_default_perm(char *templ) { int fd,c,max_attempts; size_t len; char *tst,*p; if ( templ==NULL || (len=strlen(templ))<6 ) return(-1); tst=templ+len-6; for ( p=tst ; *p ; p++ ) { if ( *p != 'X' ) return(-1); } max_attempts=1024*1024*1024; while ( max_attempts>0 ) { for ( p=tst ; *p ; p++ ) { c=rand()%(62); *p=(c<10?c+'0':c<36?c-10+'a':c-36+'A'); } fd=open(templ,O_CREAT|O_RDWR|O_EXCL,0666); if ( fd>=0 ) return(fd); max_attempts--; }; return(-1); } /*****************************************************************************/ int overscan_model(int sy,double *spy,double *spw,double *spm,overscan *o,fitsheaderset *header) { double f,sig,sw,**fbase,w; int i,j,n,k,order,nvar,used,avail; double **amatrix,*bvector,*fvars; switch ( o->type ) { case OVERSCAN_SPLINE: order=o->order; fbase=(double **)tensor_alloc_2d(double,sy,order+1); fbase_spline(fbase,order,sy); break; case OVERSCAN_POLY: order=o->order; fbase=(double **)tensor_alloc_2d(double,sy,order+1); fbase_polynomial(fbase,order,sy); break; default: order=0; fbase=(double **)tensor_alloc_2d(double,sy,order+1); fbase_polynomial(fbase,order,sy); break; } nvar=order+1; amatrix=matrix_alloc(nvar); bvector=vector_alloc(nvar); fvars =vector_alloc(nvar); avail=0; for ( k=0 ; k 0.0 ) avail++; } used=avail; for ( n=0 ; n<=(o->niter<0?0:o->niter) ; n++ ) { for ( i=0 ; initer ) { sig=0.0; sw=0.0; for ( k=0 ; k0.0 ) sig=sqrt(sig); else sig=0.0; for ( k=0 ; k= o->sigma * sig ) { spw[k]=0.0; used--; } } } } sig=0.0; sw=0.0; for ( k=0 ; k0.0 ) sig=sqrt(sig); else sig=0.0; /* just export the overscan information */ if ( header != NULL ) { char buff[80],*type; int l; switch ( o->type ) { case OVERSCAN_SPLINE: type="spline"; break; case OVERSCAN_POLY: type="polynomial"; break; default: type="const"; break; } l=snprintf(buff,80,"ficalib: %s o=%d c=",type,o->order); for ( i=0 ; i0?80-l:0),","); l+=snprintf(buff+l,(80-l>0?80-l:0),"%.1f",bvector[i]); } l+=snprintf(buff+l,(80-l>0?80-l:0)," s=%.1f n=%d/%d/%d",sig,sy,sy-avail,sy-used); fits_headerset_set_string(header,"OVERSCAN",FITS_SH_ADD,buff,NULL); } vector_free(fvars); vector_free(bvector); matrix_free(amatrix); tensor_free(fbase); return(0); } int overscan_do_vertical(fitsimage *img,char **mask,int x0,int y0,int sx,int sy,int ox,int wx,overscan *o,compar *cp,fitsheaderset *header) { int i,j,lp,np,x,y; double *line,*spw,*spy,*spm; spw =(double *)malloc(sizeof(double)*sy); spy =(double *)malloc(sizeof(double)*sy); line=(double *)malloc(sizeof(double)*wx); np=0; for ( i=0 ; i=img->sx || y<0 || y>=img->sy ) continue; else if ( mask != NULL && mask[y][x] ) continue; line[lp]=img->data[y][x]; lp++; } if ( lp>0 ) { spw[i]=1.0; spy[i]=combine_points(line,lp,cp); np++; } else { spw[i]=0.0; spy[i]=0.0; } } if ( np < o->order+1 ) /* overscan failed due to insufficient num of points */ { free(line); free(spy); free(spw); return(-1); } spm =(double *)malloc(sizeof(double)*sy); overscan_model(sy,spy,spw,spm,o,header); for ( i=0 ; idata[y0+i][x0+j] -= spm[i]; } } free(spm); free(line); free(spy); free(spw); return(0); } int overscan_do_horizontal(fitsimage *img,char **mask,int x0,int y0,int sx,int sy,int oy,int wy,overscan *o,compar *cp,fitsheaderset *header) { int i,j,lp,np,x,y; double *line,*spw,*spy,*spm; spw =(double *)malloc(sizeof(double)*sx); spy =(double *)malloc(sizeof(double)*sx); line=(double *)malloc(sizeof(double)*wy); np=0; for ( i=0 ; i=img->sx || y<0 || y>=img->sy ) continue; else if ( mask != NULL && mask[y][x] ) continue; line[lp]=img->data[y][x]; } if ( lp>0 ) { spw[i]=1.0; spy[i]=combine_points(line,lp,cp); np++; } else { spw[i]=0.0; spy[i]=0.0; } } if ( np < o->order+1 ) /* overscan failed due to insufficient num of points */ { free(line); free(spy); free(spw); return(-1); } spm =(double *)malloc(sizeof(double)*sx); overscan_model(sx,spy,spw,spm,o,header); for ( i=0 ; idata[y0+i][x0+j] -= spm[j]; } } free(spm); free(line); free(spy); free(spw); return(0); } int overscan_check(trim *area,trim *o) { if ( o->y0==area->y0 && o->sy==area->sy && abs(2*(o->x0-area->x0)+(o->sx-area->sx))>=o->sx+area->sx ) return(+1); /* vertical overscan */ else if ( o->x0==area->x0 && o->sx==area->sx && abs(2*(o->y0-area->y0)+(o->sy-area->sy))>=o->sy+area->sy ) return(-1); /* horizontal overscan */ else return(0); /* invalid overscan */ } int overscan_correction(fitsimage *img,char **mask,trim *area,overscan *scans,int nscan,compar *cp,fitsheaderset *header) { int ret,r,i; overscan *o; ret=0; for ( i=0 ; iarea.y0==area->y0 && o->area.sy==area->sy && abs(2*(o->area.x0-area->x0)+(o->area.sx-area->sx))>=o->area.sx+area->sx ) { r=overscan_do_vertical(img,mask,area->x0,area->y0,area->sx,area->sy,o->area.x0,o->area.sx,o,cp,header); if ( ! r ) ret++; } else if ( o->area.x0==area->x0 && o->area.sx==area->sx && abs(2*(o->area.y0-area->y0)+(o->area.sy-area->sy))>=o->area.sy+area->sy ) { r=overscan_do_horizontal(img,mask,area->x0,area->y0,area->sx,area->sy,o->area.y0,o->area.sy,o,cp,header); if ( ! r ) ret++; } } if ( header != NULL ) { char buff[80]; snprintf(buff,80,"ficalib: total_overscans=%d/%d",ret,nscan); fits_headerset_set_string(header,"OVERSCNS",FITS_SH_ADD,buff,NULL); } return(ret); } /*****************************************************************************/ /* fits *combine_more_images(char **files,int nfile,int frameno, compar *cp,calibdata *cd,presubdata *presubs,int npresub) { FILE *fr; fits *img,*ret; comimg *inputs; int i,j,sx,sy; char **outmask,*basename; inputs=(comimg *)malloc(sizeof(comimg)*nfile); for ( i=0 ; ii.dim != 2 ) { fprint_error("image dimension differs from 2."); return(NULL); } inputs[i].img=img; inputs[i].fr=fr; } if ( cd->sx<=0 || cd->sy<=0 ) cd->sx=sx=inputs[0].img->i.sx, cd->sy=sy=inputs[0].img->i.sy; else sx=cd->sx,sy=cd->sy; for ( i=0,j=0 ; ii.sx != sx || inputs[i].img->i.sy != sy ) j=1; } if ( j ) { fprint_error("size of input images differ"); exit(1); } if ( cd->mask==NULL ) { cd->mask=fits_mask_create_empty(sx,sy); if ( cd->inmasklist != NULL ) { if ( join_masks_from_files(cd->mask,sx,sy,cd->inmasklist) ) { fprint_error("unable to read one of the input mask files"); exit(1); } } } outmask=fits_mask_create_empty(sx,sy); ret=fits_create(); fits_copy_full_header(ret,inputs[0].img); fits_alloc_image(ret,sx,sy); fits_reset_image(ret); ret->i.curr.bscale=1.0; ret->i.curr.bzero=0.0; ret->i.bit=-32; combine_images_from_files(inputs,nfile,ret,cp,cd->mask,outmask,presubs,npresub,0); combine_cleanup(inputs,nfile); for ( i=0 ; imask[i][j] |= outmask[i][j]; } } fits_mask_free(outmask); free(inputs); return(ret); } */ /*****************************************************************************/ fitsextension *calibrate_mosaic_get_image_by_extname(fits *img,char *name,headername *hn) { fitsextension *fx; int i,l; fitsheader *hd; for ( i=0 ; inxtn ; i++ ) { if ( img->xtns[i].type != FITS_EXT_IMAGE ) continue; hd=fits_headerset_get_header(&img->xtns[i].header,hn->extname,0); if ( hd==NULL || hd->vtype != FITS_VSTR ) continue; l=strlen(name); if ( l>0 && memcmp(name,hd->vstr,l)==0 && 0<=hd->vstr[l] && hd->vstr[l]<=32 ) { fx=&img->xtns[i]; return(fx); } } return(NULL); } int calibrate_mosaic_check_sections(fits *img,mosaic *m,headername *hn) { int i,nvalid,bitpix; fitsextension *fx; if ( img==NULL || img->xtns==NULL || img->nxtn<=0 || m==NULL || m->sections==NULL ) return(0); bitpix=0; nvalid=0; for ( i=0 ; insection ; i++ ) { fx=calibrate_mosaic_get_image_by_extname(img,m->sections[i].name,hn); if ( fx != NULL && fx->x.i.dim==2 && fx->x.i.sx>0 && fx->x.i.sy>0 ) { nvalid++; if ( ! bitpix ) bitpix=fx->x.i.bit; else if ( bitpix>0 && fx->x.i.bit<0 ) bitpix=fx->x.i.bit; else if ( bitpix>0 && fx->x.i.bit>bitpix ) bitpix=fx->x.i.bit; else if ( bitpix<0 && fx->x.i.bitx.i.bit; } } if ( nvalid==m->nsection ) return(bitpix); else return(0); } double calibrate_get_flat_mean(fitsimage *flat,char **mask) { int i,j,sx,sy; double s0,s1; sx=flat->sx; sy=flat->sy; s0=s1=0.0; for ( i=0 ; idata[i][j]; s0+=1.0; } } if ( s0 <= 0.0 ) return(-1.0); else return(s1/s0); } int calibrate_image(char *input,char *output, geometry *g,mosaic *m,calibdata *cd,compar *cpover,fitsdataparam *fdp,headername *hn, fitsimage *bias,fitsimage *dark,fitsimage *flat, double flatmean,double darktime,int no_history) { FILE *fr,*fw; fits *img; char *tmpoutput; int sx,sy,i,j,bitpix; int had_bias,had_dark,had_flat; double dark_exp_scale,pscale; char **mask; double cexptime; double gain; int is_trim,is_mark_saturated,is_do_overscan; fr=fopenread(input); if ( fr==NULL ) { fprint_error("unable to open file '%s' for calibration, file skipped",input); return(-1); } img=fits_read(fr); fcloseread(fr); if ( img==NULL ) { fprint_error("unable to parse file '%s' as a FITS image, skipped",input); return(-1); } /* we have a mosaic image: */ if ( (bitpix=calibrate_mosaic_check_sections(img,m,hn)) != 0 ) { fits *out; int i,k,l,x,y,ix,iy; fitsextension *fx; fitsimage *fi; char **tmask; trim *t; out=fits_create(); /* fits_set_standard(out,NULL); */ fits_headerset_copy(&out->header,&img->header); fits_alloc_image(out,m->sx,m->sy); out->i.bit=bitpix; out->i.curr.bscale=1.0; out->i.curr.bzero=0.0; if ( out->i.bit<0 ) out->i.read.bscale=1.0,out->i.read.bzero=0.0; else out->i.read.bscale=1.0,out->i.read.bzero=(1<<(out->i.bit-1)); fits_set_image_params(out); /* fits_headerset_merge(&out->header,&img->header,1); */ /* TBD */ mask=fits_mask_create_empty(m->sx,m->sy); for ( k=0 ; ksy ; k++ ) { memset(mask[k],MASK_OUTER,m->sx); } for ( i=0 ; insection ; i++ ) { fx=calibrate_mosaic_get_image_by_extname(img,m->sections[i].name,hn); if ( fx==NULL ) /* should not happen */ continue; fi=&fx->x.i; tmask=fits_mask_read_from_header(&fx->header,fi->sx,fi->sy,NULL); fits_image_rescale(fi); t=&m->sections[i].g.image; if ( cd->saturation > 0.0 ) mark_saturated_pixels(fi,tmask,NULL,cd->saturation,cd->reset_method); /* do the real overscan correction(s) on the image: */ if ( m->sections[i].g.noverscan>0 ) overscan_correction(fi,tmask,t,m->sections[i].g.overscans,m->sections[i].g.noverscan,cpover,&fx->header); /* fprintf(stderr,"[3] m=(%d,%d) fi=(%d,%d) size=(%d,%d) offset=(%d,%d)\n",m->sx,m->sy,fi->sx,fi->sy,t->sx,t->sy,t->x0,t->y0); */ for ( k=0 ; ksy ; k++ ) { y=k+t->y0; if ( ! ( 0<=y && ysy ) ) continue; iy=m->sections[i].y0+k; if ( ! ( 0<=iy && iysy ) ) continue; for ( l=0 ; lsx ; l++ ) { x=l+t->x0; if ( ! ( 0<=x && xsx ) ) continue; ix=m->sections[i].x0+l; if ( ! ( 0<=ix && ixsx ) ) continue; out->i.data[iy][ix] = fi->data[y][x]; mask[iy][ix] = tmask[y][x]; } } fits_mask_free(tmask); } is_trim=0; /* handling mosaics was far more complicated ;) */ is_mark_saturated=0; /* already done */ is_do_overscan=0; /* already done */ fits_free(img); /* drop the original image... */ img=out; /* ... and use the freshly prepared one */ } /* we have a simple image, hopefully: */ else if ( img->i.dim != 2 ) { fprint_error("file '%s' is not a 2 dimensional FITS image, skipped",input); fits_free(img); return(-1); } else { fits_rescale(img); /* extract additional information from the header... */ mask=fits_mask_read_from_header(&img->header,img->i.sx,img->i.sy,NULL); is_trim=cd->is_trim; is_mark_saturated=1; is_do_overscan=1; } if ( cd->gain > 0.0 ) gain=cd->gain; else if ( fits_headerset_get_as_double(&img->header,hn->gain,&gain,0) ) gain=1.0; if ( fits_headerset_get_as_double(&img->header,hn->exptime,&cexptime,0) ) cexptime=-1.0; if ( (! cd->is_exptime_correction) && cexptime>0.0 && darktime>0.0 && (cd->is_combined_dark || bias==NULL) && cexptime != darktime ) fprint_warning("image '%s' cannot be properly calibrated due to the lack of bias and/or the explicit usage of --no-exptime-correction",input); /* ... done: beyond this point we do not need the header img->header */ /* * * * * * * * * * * * * * * * * * */ /* start of the real calibration (up to end, this part would be preserved */ /* in the cases when ficalib would handle FITS with multiple extensions) */ /* mark saturated pixels: */ if ( cd->saturation > 0.0 && is_mark_saturated ) mark_saturated_pixels(&img->i,mask,NULL,cd->saturation,cd->reset_method); /* do the real overscan correction(s) on the image: */ if ( g->noverscan>0 && is_do_overscan ) overscan_correction(&img->i,mask,&g->image,g->overscans,g->noverscan,cpover,&img->header); /* trim after the overscan correction (optional): */ if ( is_trim ) { /* this is the only strange part: if we have multiple frames/ext's */ /* in the future, these lines should operate on the extension array */ /* instead on the primary image of the general FITS container: */ sx=g->image.sx; sy=g->image.sy; fits_mask_trim(&mask,img->i.sx,img->i.sy,g->image.x0,g->image.y0,sx,sy,MASK_OUTER); fits_image_trim(&img->i,g->image.x0,g->image.y0,sx,sy,0.0); } else { sx=img->i.sx; sy=img->i.sy; } if ( join_masks_from_files(mask,sx,sy,cd->inmasklist) ) { fprint_error("unable to read one of the input mask files"); exit(1); } /* adjoin masks: cd->mask comes from the master frames */ if ( cd->mask != NULL ) { for ( i=0 ; imask[i][j]; } } /* do the bias subtraction (really simple): */ if ( bias != NULL && bias->sx==sx && bias->sy==sy ) { for ( i=0 ; ii.data[i][j] -= bias->data[i][j]; } } had_bias=1; } else had_bias=0; /* do the dark frame subtraction (optionally scaled by the exposure times): */ if ( dark != NULL && dark->sx==sx && dark->sy==sy ) { double dfactor; if ( ! cd->is_exptime_correction ) dfactor=1.0; else if ( cexptime>0.0 && darktime>0.0 ) dfactor=cexptime/darktime; else dfactor=1.0; for ( i=0 ; ii.data[i][j] -= dfactor*dark->data[i][j]; } } had_dark=1; dark_exp_scale=dfactor; } else { had_dark=0; dark_exp_scale=0.0; } /* do the flat correction, mark invalid pixels as 'outer' */ if ( flat != NULL && flat->sx==sx && flat->sy==sy && flatmean>0.0 ) { for ( i=0 ; idata[i][j] > 0.0 ) img->i.data[i][j] *= (flatmean/flat->data[i][j]); else { img->i.data[i][j] = 0.0; mask[i][j] |= MASK_OUTER; /* or something else? */ } } } had_flat=1; } else had_flat=0; if ( cd->postmultiply != 0.0 ) { for ( i=0 ; ii.data[i][j] *= cd->postmultiply; } } pscale=cd->postmultiply; } else if ( cd->postscale != 0.0 ) { double s0,s1,m; s0=s1=0.0; for ( i=0 ; ii.data[i][j]; } } m=cd->postscale*s0/s1; for ( i=0 ; ii.data[i][j] *= m; } } pscale=m; } else pscale=0.0; if ( cd->is_remove_horizontal_stripes ) { double *arr,avg; arr=(double *)malloc(sizeof(double)*sx); for ( i=0 ; ii.data[i][j]; } avg=median(arr,sx); for ( j=0 ; ji.data[i][j] -= avg; } } free(arr); arr=NULL; } /* the end of the real calibration per standalone image */ /* * * * * * * * * * * * * * * * * * */ if ( output==NULL || strcmp(output,"-")==0 || strcmp(output,"/dev/stdout")==0 ) tmpoutput=NULL; else { tmpoutput=NULL; strappendf(&tmpoutput,"%s.XXXXXX",output); } if ( tmpoutput==NULL ) fw=stdout; else { int fh; fh=mkstemp_default_perm(tmpoutput); fw=fdopen(fh,"wb"); } if ( fw==NULL ) { fprint_error("unable to create file '%s'",output); if ( tmpoutput != NULL ) free(tmpoutput); fits_mask_free(mask); fits_free(img); return(-1); } if ( is_trim ) { char buff[80]; fitsheaderset *header; double crpix1,crpix2; header=&img->header; sprintf(buff,"[%d:%d,%d:%d]", g->image.x0+1,g->image.x0+g->image.sx, g->image.y0+1,g->image.y0+g->image.sy); fits_headerset_set_integer(header,"WCSDIM",FITS_SH_ADD,1,NULL); fits_headerset_set_double(header,"LTM1_1",FITS_SH_ADD,1.0,NULL); fits_headerset_set_double(header,"LTM2_2",FITS_SH_ADD,1.0,NULL); fits_headerset_set_string(header,"WAT0_001",FITS_SH_ADD,"system=physical",NULL); fits_headerset_set_string(header,"WAT1_001",FITS_SH_ADD,"wtype=linear",NULL); fits_headerset_set_string(header,"WAT2_001",FITS_SH_ADD,"wtype=linear",NULL); fits_headerset_set_string(header,"CCDSEC",FITS_SH_ADD,buff,NULL); fits_headerset_set_double(header,"LTV1",FITS_SH_ADD,-(double)g->image.x0,NULL); fits_headerset_set_double(header,"LTV2",FITS_SH_ADD,-(double)g->image.y0,NULL); fits_headerset_delete_all(header,"DATASEC"); fits_headerset_delete_all(header,"BIASSEC"); fits_headerset_delete_all(header,"TRIMSEC"); if ( (! fits_headerset_get_as_double(header,"CRPIX1",&crpix1,0)) && (! fits_headerset_get_as_double(header,"CRPIX1",&crpix2,0)) ) { crpix1-=g->image.x0; crpix2-=g->image.y0; fits_headerset_set_double(header,"CRPIX1",FITS_SH_FIRST,crpix1,NULL); fits_headerset_set_double(header,"CRPIX2",FITS_SH_FIRST,crpix2,NULL); } } if ( had_bias || cd->is_combined_dark ) { fitsheaderset *header; char buff[80]; header=&img->header; snprintf(buff,80,"ficalib: zero: bias=\"%s\"",cd->inputbias); fits_headerset_set_string(header,"ZEROCOR",FITS_SH_ADD,buff,NULL); } if ( had_dark ) { fitsheaderset *header; char buff[80]; header=&img->header; snprintf(buff,80,"ficalib: dark: expscale=%.3f dark=\"%s\"",dark_exp_scale,cd->inputdark); fits_headerset_set_string(header,"DARKCOR",FITS_SH_ADD,buff,NULL); } if ( had_flat ) { fitsheaderset *header; char buff[80],bcmm[80]; header=&img->header; snprintf(buff,80,"ficalib: flat: mean=%.1f flat=\"%s\"",flatmean,cd->inputflat); fits_headerset_set_string(header,"FLATCOR",FITS_SH_ADD,buff,NULL); if ( cd->flatpoly != NULL ) { int i,n,nvar; nvar=(cd->gainorder+1)*(cd->gainorder+2)/2; n=0; for ( i=0 ; i0?",%.2f":"%.2f"), gain*cd->flatpoly[i]/flatmean); } sprintf(bcmm,"[%.2f]",gain*cd->flatresd/flatmean); fits_headerset_set_string(header,hn->gainpoly,FITS_SH_ADD,buff,bcmm); fits_headerset_set_double(header,hn->gainvmin,FITS_SH_ADD,gain*cd->flatvmin/flatmean,NULL); } } if ( pscale != 0.0 ) { fitsheaderset *header; char buff[80]; header=&img->header; snprintf(buff,80,"ficalib: post-multiply: factor=%.4f",pscale); fits_headerset_set_string(header,"PSTSCALE",FITS_SH_ADD,buff,NULL); fits_headerset_set_double(header,"MULTIPLD",FITS_SH_ADD,pscale,"ficalib: post-multiply"); } if ( ! no_history ) fits_history_export_command_line(img,"ficalib",FITSH_FICALIB_VERSION,cd->argc,cd->argv); if ( fdp->bitpix ) { img->i.bit=fdp->bitpix; } if ( fdp->is_scale ) { img->i.read.bscale=fdp->bscale, img->i.read.bzero=fdp->bzero; } else if ( img->i.bit<0 ) { img->i.read.bscale=1.0, img->i.read.bzero=0.0; } fits_set_image_params(img); fits_backscale(img,img->i.read.bscale,img->i.read.bzero); mark_integerlimited_pixels(&img->i,mask,img->i.bit,1,MASK_OVERSATURATED,MASK_OVERSATURATED); fits_mask_export_as_header(&img->header,1,mask,sx,sy,NULL); fits_write(fw,img); fits_mask_free(mask); fits_free(img); fclosewrite(fw); #ifdef HOST_WIN32 if ( tmpoutput != NULL ) { rename(tmpoutput,output); free(tmpoutput); tmpoutput=NULL; } #else if ( tmpoutput != NULL ) { int r; if ( (r=link(tmpoutput,output)) && errno==EEXIST ) { unlink(output); r=link(tmpoutput,output); } if ( ! r ) unlink(tmpoutput); free(tmpoutput); tmpoutput=NULL; } #endif return(0); } /*****************************************************************************/ int calibrate_fit_flatpoly(double **data,int sx,int sy,char **inmask, int order,double *flatpoly,double *flatresd,double *flatvmin) { int i,j,k,l,nvar; double x,y,s2,s0,sig,z,dz; double **amatrix,*bvector,*fvars,vmin; int niter,iiter; double sigma; char **mask; if ( data==NULL || sx<=0 || sy<=0 || flatpoly==NULL || order<0 ) return(-1); nvar=(order+1)*(order+2)/2; amatrix=matrix_alloc(nvar); bvector=vector_alloc(nvar); fvars =vector_alloc(nvar); niter=2; sigma=2.0; mask=fits_mask_create_empty(sx,sy); if ( inmask != NULL ) { for ( i=0 ; i0 && s2>0 ) sig=sqrt(s2/s0); else sig=0.0; if ( flatresd != NULL ) *flatresd=sig; if ( flatvmin != NULL ) *flatvmin=vmin; if ( iiter >= niter ) continue; for ( i=0 ; ix0,&image->y0,&image->sx,&image->sy); if ( t<4 ) return(1); if ( image->sxx0 ) { t=image->sx,image->sx=image->x0,image->x0=t; } if ( image->syy0 ) { t=image->sy,image->sy=image->y0,image->y0=t; } image->sx=image->sx-image->x0+1; image->sy=image->sy-image->y0+1; return(0); } int ficalib_parse_overscan_data(char *overscanspec,overscan *o) { int i,t,x1,y1,x2,y2; int niter,order,type; double sigma; char *area; x1=y1=x2=y2=0; niter=0; sigma=3.0; order=2; type=OVERSCAN_SPLINE; area=NULL; i=scanpar(overscanspec,SCANPAR_DEFAULT, "area:%s",&area, "iterations:%d",&niter, "sigma:%g",&sigma, "order:%d",&order, "polynomial:" SNf(OVERSCAN_POLY) , &type, "spline:" SNf(OVERSCAN_SPLINE) , &type, NULL); if ( area != NULL ) { if ( sscanf(area,"%d:%d:%d:%d",&x1,&y1,&x2,&y2)<4 ) i=1; } if ( i ) return(1); if ( x2area.x0=x1; o->area.sx=x2-x1+1; o->area.y0=y1; o->area.sy=y2-y1+1; o->type=type; o->order=order; o->niter=niter; o->sigma=sigma; return(0); } int ficalib_parse_mosaic_data(char *mstr,mosaic *m) { char *wms,**mtokens,*wss,**stokens,*cmd[4]; int i,j,k,l,n; section *s; wms=strdup(mstr); remove_spaces_and_comments(wms); for ( i=0 ; wms[i] ; i++ ) { if ( wms[i]=='(' ) wms[i]='['; else if ( wms[i]==')' ) wms[i]=']'; } m->nsection=0; m->sections=NULL; for ( i=0,l=0 ; wms[i] ; i++ ) { if ( wms[i]=='[' ) l++; else if ( wms[i]==']' ) l--; else if ( wms[i]==',' || wms[i]==';' ) { if ( l>0 ) wms[i]=','; else wms[i]=';'; } } if ( l != 0 ) { free(wms); return(1); } mtokens=tokenize_char_dyn(wms,';'); if ( mtokens==NULL ) { free(wms); return(1); } else if ( mtokens[0]==NULL ) { free(mtokens); free(wms); return(1); } for ( n=0 ; mtokens[n] != NULL ; n++ ) { wss=mtokens[n]; l=strlen(wss); if ( l>2 && (wss[0]=='[') && (wss[l-1]==']') ) { int x,y; overscan o; wss[l-1]=0; wss++; m->sections=(section *)realloc(m->sections,sizeof(section)*(m->nsection+1)); s=&m->sections[m->nsection]; m->nsection++; s->x0=0; s->y0=0; s->g.image.x0=0; s->g.image.y0=0; s->g.image.sx=0; s->g.image.sy=0; s->g.overscans=NULL; s->g.noverscan=0; for ( i=0,l=0 ; wss[i] ; i++ ) { if ( wss[i]=='[' ) l++; else if ( wss[i]==']' ) l--; else if ( wss[i]==',' || wss[i]==';' ) { if ( l>0 ) wss[i]=','; else wss[i]=';'; } } if ( l != 0 ) { free(mtokens);free(wms); return(1); } stokens=tokenize_char_dyn(wss,';'); if ( stokens==NULL ) { free(mtokens);free(wms); return(1); } else if ( stokens[0]==NULL ) { free(stokens);free(mtokens);free(wms); return(1); } for ( j=0 ; stokens[j] != NULL ; j++ ) { k=tokenize_char(stokens[j],cmd,'=',2); if ( k != 2 ) { free(stokens);free(mtokens);free(wms); return(1); } l=strlen(cmd[1]); if ( strcmp(cmd[0],"name")==0 ) { strncpy(s->name,cmd[1],16); s->name[15]=0; } else if ( strcmp(cmd[0],"offset")==0 && sscanf(cmd[1],"[%d,%d]",&x,&y)==2 ) { s->x0=x; s->y0=y; } else if ( strcmp(cmd[0],"image")==0 && cmd[1][0]=='[' && cmd[1][l-1]==']' ) { cmd[1][l-1]=0; k=ficalib_parse_imagetrim_data(cmd[1]+1,&s->g.image); if ( k ) { free(stokens);free(mtokens);free(wms); return(1); } } else if ( strcmp(cmd[0],"overscan")==0 && cmd[1][0]=='[' && cmd[1][l-1]==']' ) { cmd[1][l-1]=0; k=ficalib_parse_overscan_data(cmd[1]+1,&o); if ( k ) { free(stokens);free(mtokens);free(wms); return(1); } s->g.overscans=(overscan *)realloc(s->g.overscans,sizeof(overscan)*(s->g.noverscan+1)); s->g.overscans[s->g.noverscan]=o; s->g.noverscan++; } else { free(stokens);free(mtokens);free(wms); return(1); } } free(stokens); } else { int x,y; k=tokenize_char(mtokens[n],cmd,'=',2); if ( k != 2 ) { free(mtokens);free(wms); return(1); } else if ( strcmp(cmd[0],"size")==0 && sscanf(cmd[1],"[%d,%d]",&x,&y)==2 ) { m->sx=x; m->sy=y; } else { free(mtokens);free(wms); return(1); } } } free(mtokens); free(wms); return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { char **inputlist,**outputlist,**inmasklist,*rewriterule; fits *bias,*dark,*flat; double flatmean,darktime; FILE *fr; int ninimg; int i,n,is_help,apply_mask,no_rewrite,no_history; char *fdpstring,*overmodestr,*imgarea,*gainstr, *hdrdefstr,**overscanlist,*mosaicstr; compar cpover; fitsdataparam fdp; calibdata cd; headername hn; geometry g; mosaic m; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; is_help=is_verbose=is_comment=no_rewrite=no_history=0; inputlist=outputlist=NULL; rewriterule=NULL; cd.inputbias=cd.inputdark=cd.inputflat=NULL; inmasklist=NULL; apply_mask=0; fdp.bitpix=-32;fdp.is_scale=0;fdp.bscale=1.0;fdp.bzero=0.0; fdpstring=NULL,hdrdefstr=NULL,overscanlist=NULL; cpover.mode=COM_MODE_MED; cpover.ignore_flag=0; cpover.logicalmethod=0; cpover.niter=0; cpover.lower=cpover.upper=3.0; overmodestr=NULL; hn.exptime="EXPTIME"; hn.date="DATE-OBS"; hn.time="TIME-OBS"; hn.jd="JD"; hn.hjd="HJD"; hn.jy="JY"; hn.hjy="HJY"; hn.gain="GAIN"; hn.gainpoly="GAINPOLY"; hn.gainvmin="GAINVMIN"; hn.extname="EXTNAME"; imgarea=NULL; g.image.x0=0; g.image.y0=0; g.image.sx=0; g.image.sy=0; g.overscans=NULL; g.noverscan=0; cd.argc=argc; cd.argv=argv; cd.is_trim=0; cd.is_exptime_correction=1; cd.saturation=0; cd.reset_method=0; cd.postscale=0.0; cd.postmultiply=0.0; cd.is_remove_horizontal_stripes=0; cd.gain=1.0; cd.gainorder=0; gainstr=NULL; m.sections=NULL; m.nsection=0; m.sx=m.sy=0; mosaicstr=NULL; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help|--short-help|--help-short:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-b|--bitpix:%d",&fdp.bitpix, "--data:%s",&fdpstring, "-B|--input-master-bias:%s",&cd.inputbias, "-D|--input-master-dark:%s",&cd.inputdark, "-F|--input-master-flat:%s",&cd.inputflat, "--overscan-combination:%s",&overmodestr, "--overscan:%Dt",&overscanlist, "--image:%s",&imgarea, "--trim:%SN1f",&cd.is_trim, "--no-trim:%SN0f",&cd.is_trim, "--mosaic:%Cr",&mosaicstr, "--exptime-correction:%SN1f",&cd.is_exptime_correction, "--no-exptime-correction:%SN0f",&cd.is_exptime_correction, "-c|--scale|--post-scale:%g",&cd.postscale, "-m|--multiply|--post-multiply:%g",&cd.postmultiply, "--leak-lower-upper|--lu:%N1f",&cd.reset_method, "--leak-left-right|--lr:%N2f",&cd.reset_method, "--leak-any|--an:%N3f",&cd.reset_method, "--horizontal-stripe-removal:%f",&cd.is_remove_horizontal_stripes, "-s|--saturation:%g",&cd.saturation, "-i|--input:%Mt",&inputlist, "-o|--output:%Mt",&outputlist, "-r|--rewrite-output-name:%s",&rewriterule, "-M|--input-mask:%t",&inmasklist, "-a|--apply-mask:%f",&apply_mask, "--no-rewrite|--no-clobber:%f",&no_rewrite, "--clobber:%SN0f",&no_rewrite, "--no-history:%f",&no_history, "--history:%SN0f",&no_history, "-g|--gain:%s",&gainstr, "--gain-order:%d",&cd.gainorder, "--header:%s",&hdrdefstr, "--comment:%f",&is_comment,"(C):%f",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-*|+*:%e", "*:%l",&inputlist, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"ficalib",FITSH_FICALIB_VERSION,is_help); return(0); } else if ( 10 ) { fprint_warning("no trim section has been specified, overscans are ignored"); if ( g.overscans != NULL ) free(g.overscans); g.noverscan=0; g.overscans=NULL; } else if ( g.image.sx>0 && g.image.sy>0 && g.noverscan>0 ) { trim *o; for ( i=0 ; ix0,o->y0,o->x0+o->sx-1,o->y0+o->sy-1); } } } ninimg=count_list(inputlist); if ( outputlist==NULL ) outputlist=inputlist; i=count_list(outputlist); if ( i != ninimg ) { fprint_error("number of input and output images differ"); return(1); } if ( rewriterule != NULL ) { char **newlist,*from,*to; if ( strchr(rewriterule,'|') == NULL ) { from="*"; to=rewriterule; } else if ( strchr(rewriterule,'|') != strrchr(rewriterule,'|') ) { fprint_error("invalid re-write pattern '%s'.",rewriterule); return(1); } else { char *p; int flen; p=strchr(rewriterule,'|'); flen=p-rewriterule; if ( flen<=0 ) { from="*"; to=p+1; } else { from=(char *)malloc(flen+1); memcpy(from,rewriterule,flen); from[flen]=0; to=p+1; } } newlist=(char **)malloc(sizeof(char *)*(ninimg+1)); for ( i=0 ; i %s\n",outputlist[i],newlist[i]); */ } outputlist=newlist; /* return(0); */ } cd.sx=cd.sy=0; cd.mask=NULL; cd.inmasklist=inmasklist; /* reading bias image if any */ if ( cd.inputbias != NULL ) { if ( (fr=fopenread(cd.inputbias))==NULL ) { fprint_error("unable to open input bias image file '%s'",cd.inputbias); return(1); } bias=fits_read(fr); fcloseread(fr); if ( bias==NULL ) { fprint_error("unable to parse input bias file as FITS data."); return(1); } if ( bias->i.dim != 2 ) { fprint_error("bias image dimension differs from 2."); return(1); } fits_rescale(bias); cd.sx=bias->i.sx, cd.sy=bias->i.sy; cd.mask=fits_mask_read_from_header(&bias->header,cd.sx,cd.sy,NULL); } else bias=NULL; /* reading dark image if any */ if ( cd.inputdark != NULL ) /* read from file (-iD ...) */ { if ( (fr=fopenread(cd.inputdark))==NULL ) { fprint_error("unable to open input dark image file '%s'",cd.inputdark); return(1); } dark=fits_read(fr); if ( dark==NULL ) { fprint_error("unable to parse input dark file as FITS data."); return(1); } if ( dark->i.dim != 2 ) { fprint_error("dark image dimension differs from 2."); return(1); } if ( cd.sx>0 && cd.sy>0 && ( dark->i.sx != cd.sx || dark->i.sy != cd.sy ) ) { fprint_error("dark image size differs from the expected image size."); return(1); } fits_rescale(dark); if ( cd.mask==NULL ) { cd.sx=dark->i.sx, cd.sy=dark->i.sy; cd.mask=fits_mask_read_from_header(&dark->header,cd.sx,cd.sy,NULL); } else fits_mask_mask_from_header(cd.mask,&dark->header,cd.sx,cd.sy,NULL); } else dark=NULL; if ( (! cd.is_exptime_correction) && dark != NULL && bias != NULL ) { int i,j; for ( i=0 ; ii.data[i][j] += bias->i.data[i][j]; } } fits_free(bias); /* we do it because of this step, mainly */ bias=NULL; cd.is_combined_dark=1; } else cd.is_combined_dark=0; /* reading flat image if any */ if ( cd.inputflat != NULL ) /* read from file (-iF ...) */ { if ( (fr=fopenread(cd.inputflat))==NULL ) { fprint_error("unable to open input flat image file '%s'",cd.inputflat); return(1); } flat=fits_read(fr); if ( flat==NULL ) { fprint_error("unable to parse input flat file as FITS data."); return(1); } if ( flat->i.dim != 2 ) { fprint_error("flat image dimension differs from 2."); return(1); } if ( cd.sx>0 && cd.sy>0 && ( flat->i.sx != cd.sx || flat->i.sy != cd.sy ) ) { fprint_error("flat image size differs from the expected image size."); return(1); } fits_rescale(flat); if ( cd.mask==NULL ) { cd.sx=flat->i.sx, cd.sy=flat->i.sy; cd.mask=fits_mask_read_from_header(&flat->header,cd.sx,cd.sy,NULL); } else fits_mask_mask_from_header(cd.mask,&flat->header,cd.sx,cd.sy,NULL); } else flat=NULL; if ( flat != NULL ) { flatmean=calibrate_get_flat_mean(&flat->i,cd.mask); cd.flatpoly=(double *)malloc(sizeof(double)*(cd.gainorder+1)*(cd.gainorder+2)/2); calibrate_fit_flatpoly(flat->i.data,cd.sx,cd.sy,cd.mask,cd.gainorder,cd.flatpoly,&cd.flatresd,&cd.flatvmin); } else { flatmean=0.0; cd.flatpoly=NULL; } if ( dark != NULL ) { if ( fits_headerset_get_as_double(&dark->header,hn.exptime,&darktime,0) ) darktime=-1.0; } else darktime=-1.0; srand_auto(); /* do the calibration for all input images: */ for ( n=0 ; ni; else ibias=NULL; if ( dark != NULL ) idark=&dark->i; else idark=NULL; if ( flat != NULL ) iflat=&flat->i; else iflat=NULL; /* check whether the output file exists (and it is a regular file): */ if ( no_rewrite && (!stat(outputlist[n],&st)) && S_ISREG(st.st_mode) ) { if ( is_verbose ) { fprint_warning("output file '%s' exists, re-calibration is skipped",outputlist[n]); } continue; } /* the main calibration stuff per file: */ calibrate_image(inputlist[n],outputlist[n],&g,&m,&cd,&cpover, &fdp,&hn,ibias,idark,iflat,flatmean,darktime,no_history); } /* for ( n=0 ; n #include #include #include #include #include #include #include #include "fitsh.h" #include "tensor.h" #include "stars.h" #include "psf.h" #include "weight.h" /*****************************************************************************/ static int weight_compare(const void *v1,const void *v2) { weight *w1,*w2; w1=(weight *)v1, w2=(weight *)v2; if ( w1->x < w2->x ) return(-1); else return(1); } int weight_sort(weightlist *wl) { if ( wl==NULL || wl->weights==NULL || wl->nweight<=0 ) return(1); if ( wl->nweight>1 ) { qsort(wl->weights,wl->nweight,sizeof(weight),weight_compare); } return(0); } /*****************************************************************************/ weight *weight_get_closest(weightlist *wl,double x0,double y0) { int best,min,max,mid; double dist,xc,yc,xc0,yc0,xx,yy,xdist,ydist,cdist,mindist,maxdist; weight *ww; int outl,outr,pl,pr; if ( wl==NULL || wl->weights==NULL || wl->nweight<=0 ) return(NULL); min=0; max=wl->nweight; while ( max>min ) { mid=(min+max)/2; dist=x0-wl->weights[mid].x; if ( fabs(dist)<1e-10 ) break; else if ( dist>0.0 ) min=mid+1; else max=mid; } xc0=wl->weights[mid].x, yc0=wl->weights[mid].y; xdist=fabs(x0-xc0), ydist=fabs(y0-yc0); mindist=xdist*xdist+ydist*ydist; maxdist=xdist+ydist; best=mid; for ( outl=outr=1,pl=best-1,pr=best+1 ; outl || outr ; pl--,pr++ ) { if ( outl ) { if ( pl>=0 ) { xc=wl->weights[pl].x, yc=wl->weights[pl].y; xx=x0-xc; if ( xxnweight ) { xc=wl->weights[pr].x, yc=wl->weights[pr].y; xx=xc-x0; if ( xxweights[best]; return(ww); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int weight_get_intersec_list(weightlist *wl,int x0,int y0,int sx,int sy,int *list,int maxcnt) { int n,fr,fl,xr,xl,i,cnt,yu,yd; weight *ww; if ( wl==NULL || wl->weights==NULL || wl->nweight<=0 ) return(-1); xl=x0-1-wl->hsize; xr=x0+sx+1+wl->hsize; yd=y0-1-wl->hsize; yu=y0+sy+1+wl->hsize; fl=0,n=wl->nweight; while ( n ) { if ( xl>wl->weights[fl+n/2].ix ) fl+=n/2+1,n-=n/2+1; else n=n/2; }; fr=0,n=wl->nweight; while ( n ) { if ( xr>wl->weights[fr+n/2].ix ) fr+=n/2+1,n-=n/2+1; else n=n/2; }; cnt=0; for ( i=fl ; i<=fr && ( maxcnt<0 || cntweights[i]; if ( yd <= ww->iy && ww->iy <= yu ) { list[cnt]=i; cnt++; } } return(cnt); } /*****************************************************************************/ fitsh-0.9.2/src/star-cand-pp.c0000644000175000017500000001510312771510522014501 0ustar apalapal/*****************************************************************************/ /* star-cand-pp.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Star candidate searching based on the (old) `parabola peak' algorithm. */ /*****************************************************************************/ #include #include #include #include #include #include "io/iof.h" #include "fitsmask.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/point.h" #include "link/floodfill.h" #include "fitsh.h" #include "common.h" #include "stars.h" /*****************************************************************************/ int search_star_candidates(fitsimage *img,char **mask,candidate **rcands,int *rncand,range *srcrange,double threshold,spatial *spbg,double skysigma) { candidate *cands,*wc; int ncand; int i,j,k,l,sx,sy,imin,imax,jmin,jmax; double w,is,is2,ns,ia,ia2,na; double pfit[6],a,ax,ay,axx,axy,ayy,det,tr,cx,cy,peak,amp,bg; sx=img->sx,sy=img->sy; ncand=0;cands=NULL; if ( srcrange==NULL ) { imin=2,imax=sy-3, jmin=2,jmax=sx-3; } else { imin=srcrange->ymin,imax=srcrange->ymax; jmin=srcrange->xmin,jmax=srcrange->xmax; if ( imin>imax ) i=imin,imin=imax,imax=i; if ( jmin>jmax ) j=jmin,jmin=jmax,jmax=j; } if ( imin<2 ) imin=2; if ( imax>=sy-2 ) imax=sy-3; if ( jmin<2 ) jmin=2; if ( jmax>=sx-2 ) jmax=sx-3; for ( i=imin ; i<=imax ; i++ ) { for ( j=jmin ; j<=jmax ; j++ ) { double sky; if ( mask != NULL ) { if ( mask[i][j] || mask[i][j+1] || mask[i][j-1] || mask[i+1][j] || mask[i-1][j] ) continue; } w=img->data[i][j]; if ( ! ( img->data[i][j-1]data[i][j+1]data[i-1][j]data[i+1][j]data[i-1][j];l=0; if ( img->data[i-1][j-1]data[i-1][j+1]data[i+1][j];l=0; if ( img->data[i+1][j-1]data[i+1][j+1]data[i][j-1];l=0; if ( img->data[i-1][j-1]data[i+1][j-1]data[i][j+1];l=0; if ( img->data[i-1][j+1]data[i+1][j+1]data[i+k][j+l]; is+=w,is2+=w*w;ns++; } } is/=(double)ns;is2/=(double)ns; ia=ia2=0.0;na=0; for ( k=-1 ; k<=1 ; k++ ) { w=img->data[i-2][j+k];ia+=w,ia2+=w*w; w=img->data[i+2][j+k];ia+=w,ia2+=w*w; w=img->data[i+k][j-2];ia+=w,ia2+=w*w; w=img->data[i+k][j+2];ia+=w,ia2+=w*w; na+=4; } ia/=(double)na;ia2/=(double)na; if ( ! ( is>ia+skysigma ) ) continue; fit_small_parabola_block(img,j,i,pfit); a=pfit[0],ax=pfit[1],ay=pfit[2], axx=pfit[3],axy=pfit[4],ayy=pfit[5]; det=axx*ayy-axy*axy; tr=axx+ayy; if ( det<=0.0 || tr>=0.0 ) continue; cx=-(+ayy*ax-axy*ay)/det, cy=-(-axy*ax+axx*ay)/det; if ( fabs(cx)>1 || fabs(cy)>1 ) continue; peak=a+ax*cx+ay*cy+0.5*(axx*cx*cx+2.0*axy*cx*cy+ayy*cy*cy); if ( spbg==NULL ) sky=0.0; else sky=eval_2d_poly((double)j,(double)i,spbg->order,spbg->coeff,spbg->ox,spbg->oy,spbg->scale); if ( peak-sky < threshold && sky>0.0 && threshold>0.0 ) continue; bg=sky; amp=peak-sky; cands=(candidate *)realloc(cands,sizeof(candidate)*(ncand+1)); wc=&cands[ncand]; wc->ix=j,wc->cx=cx+(double)j+0.5; wc->iy=i,wc->cy=cy+(double)i+0.5; wc->peak=peak; wc->amp=amp; wc->bg=bg; wc->sxx=-axx/amp; wc->sxy=-axy/amp; wc->syy=-ayy/amp; wc->marked=0; wc->ipoints=NULL; wc->nipoint=0; wc->area=0.0; wc->noise=0.0; ncand++; } } if ( rcands != NULL ) *rcands=cands; if ( rncand != NULL ) *rncand=ncand; return(0); } /*****************************************************************************/ typedef struct { fitsimage *img; int bx,by; int bsx,bsy; int *fillmask; double cx,cy; } fillparam; int getpixel_fill(void *param,int x,int y) { fillparam *fp; double iix,iiy,dx,dy,w; fp=(fillparam *)param; if ( x<0 || y<0 || x>=fp->bsx || y>=fp->bsy ) return(1); if ( fp->fillmask[y*fp->bsx+x] ) return(1); if ( x==fp->bsx/2 && y==fp->bsy/2 ) return(0); x+=fp->bx,y+=fp->by; if ( x<1 || y<1 || x>=fp->img->sx-1 || y>=fp->img->sy-1 ) return(1); iix=(fp->img->data[y-1][x+1]-fp->img->data[y-1][x-1])+ (fp->img->data[y ][x+1]-fp->img->data[y ][x-1])+ (fp->img->data[y+1][x+1]-fp->img->data[y+1][x-1]), iiy=(fp->img->data[y+1][x-1]-fp->img->data[y-1][x-1])+ (fp->img->data[y+1][x ]-fp->img->data[y-1][x ])+ (fp->img->data[y+1][x+1]-fp->img->data[y-1][x+1]); dx=-((double)x+0.5-fp->cx); dy=-((double)y+0.5-fp->cy); w=iix*dx+iiy*dy; if ( w<0.0 ) return(1); if ( w*w <= (dx*dx+dy*dy)*(iix*iix+iiy*iiy)*0.9 ) return(1); return(0); } void setpixel_fill(void *param,int x,int y) { fillparam *fp; fp=(fillparam *)param; if ( x<0 || y<0 || x>=fp->bsx || y>=fp->bsy ) return; fp->fillmask[y*fp->bsx+x]=1; } int markout_candidates(fitsimage *img,char **mask,candidate *cands,int ncand) { int i,j,k,sx,sy,n,bx,by; double avgd,bg; int *fillmask; int hbs,bs; fillparam fp; candidate *wc; if ( ncand == 0 ) return(0); if ( ncand < 0 ) return(1); sx=img->sx,sy=img->sy; avgd=sqrt((double)sx*(double)sy/(double)ncand); hbs=(int)(avgd*2.0); hbs=10; bs=2*hbs; fillmask=(int *)malloc(sizeof(int)*bs*bs); for ( n=0 ; nmarked=0; fp.img=img; fp.bsx=fp.bsy=bs; fp.bx=bx=wc->ix-hbs; fp.by=by=wc->iy-hbs; fp.cx=wc->cx, fp.cy=wc->cy; for ( i=0 ; i=sy-1 || lj>=sx-1 ) continue; if ( mask != NULL && mask[li][lj] ) continue; if ( fillmask[i*bs+j] ) k++; } } if ( k<9 ) { wc->marked=1; continue; } wc->nipoint=k; wc->ipoints=(ipoint *)malloc(sizeof(ipoint)*k); bg=0; for ( i=0,k=0 ; i=sy-1 || lj>=sx-1 ) continue; if ( mask != NULL && mask[li][lj] ) continue; if ( k==0 || img->data[li][lj]data[li][lj]; if ( fillmask[i*bs+j] ) wc->ipoints[k].x=lj, wc->ipoints[k].y=li, k++; } } wc->bg=bg; wc->amp=wc->peak-bg; wc->area=(double)wc->nipoint; wc->noise=0.0; } free(fillmask); return(0); } fitsh-0.9.2/src/fiinfo-image.c0000644000175000017500000002610212771247703014553 0ustar apalapal/*****************************************************************************/ /* fiinfo-image.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line user interface to get some statistics from FITS data: */ /* Gather information about FITS images. */ /*****************************************************************************/ #include #include #include #include #include #include #include #include "fitsh.h" #include "fitsmask.h" #include "math/spline/biquad.h" #include "math/spline/bicubic.h" #include "math/spline/spline.h" #include "math/fit/lmfit.h" #include "statistics.h" #include "math/poly.h" #include "math/polyfit.h" #include "math/splinefit.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "link/linkpoint.h" #include "tensor.h" #include "common.h" #include "fiinfo.h" /*****************************************************************************/ int create_link_background(fitsimage *img,char **mask,fitsimage *bgi,int nx,int ny) { double **bqc; int sx,sy,i,j,mi,mj /*,k,l,ct,cm */; linkpoint **lparr; if ( img==NULL || img->data==NULL ) return(1); if ( bgi==NULL || bgi->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); if ( bgi->sx != sx || bgi->sy != sy ) return(1); bqc=tensor_alloc_2d(double,2*sx+1,2*sy+1); biquad_coeff(img->data,sx,sy,bqc,mask); for ( i=0 ; idata[i][j]=biquad_scatter(bqc,j,i); } } lparr=linkpoint_create(bgi->data,sx,sy,NULL,mask,-1); linkpoint_reconnect(lparr,sx,sy); for ( i=0 ; idata[i][j]=0.0;continue; } mi=lparr[i][j].my, mj=lparr[i][j].mx; /*ct=cm=0; for ( k=-1 ; k<=1 ; k++ ) { if ( i+k<0 || i+k>=sy ) continue; for ( l=-1 ; l<=1 ; l++ ) { if ( j+l<0 || j+l>=sx || ( k==0 && l==0 ) ) continue; if ( mask != NULL && mask[i+k][j+l] ) continue; ct++; if ( lparr[i+k][j+l].mx==mj && lparr[i+k][j+l].my==mi ) cm++; } } if ( cm>=1 || ct<1 )*/ bgi->data[i][j]=img->data[mi][mj]; /*else { bgi->data[i][j]=0.0; cm=ct=0; for ( k=-1 ; k<=1 ; k++ ) { if ( i+k<0 || i+k>=sy ) continue; for ( l=-1 ; l<=1 ; l++ ) { if ( j+l<0 || j+l>=sx || ( k==0 && l==0 ) ) continue; if ( mask != NULL && mask[i+k][j+l] ) continue; ct++; if ( lparr[i+k][j+l].mx != mj || lparr[i+k][j+l].my != mi ) { bgi->data[i][j]+=img->data[lparr[i+k][j+l].my][lparr[i+k][j+l].mx]; cm++; } } } if ( cm>0 ) bgi->data[i][j]/=(double)cm; }*/ } } /* do spline smoothing */ if ( nx>0 && ny>0 ) { double **scc,**bcc,x,y; point *points; int npoint; scc=tensor_alloc_2d(double,nx+1,ny+1); /* spline control points */ bcc=tensor_alloc_2d(double,2*nx+2,2*ny+2); /* bicubic coeffs */ points=(point *)malloc(sizeof(point)*sx*sy);/* points for fitting... */ npoint=0; for ( i=0 ; idata[i][j]; points[npoint].weight=1.0; npoint++; } } fit_2d_spline(0,sx,nx,0,sy,ny,points,npoint,scc); bicubic_coeff(scc,nx+1,ny+1,bcc,NULL); for ( i=0 ; idata[i][j]=bicubic_inter(bcc,x,y); } } free(points); tensor_free(bcc); tensor_free(scc); } tensor_free(lparr); return(0); } /*****************************************************************************/ int fits_stat_basic(fitsimage *img,char **mask,double *rmin,double *rmax,double *rmean,double *rstdd) { int i,j,n,is_first; double mean,mean2,min,max,stdd,w; min=max=mean=mean2=0.0;n=0; is_first=1; for ( i=0 ; isy ; i++ ) { for ( j=0 ; jsx ; j++ ) { w=img->data[i][j]; if ( mask != NULL && mask[i][j] ) continue; mean +=w; mean2+=w*w; if ( is_first ) min=max=w,is_first=0; else if ( wmax ) max=w; n++; } } mean /=(double)n; mean2/=(double)n; stdd =sqrt(mean2-mean*mean); if ( rmin != NULL ) *rmin =min; if ( rmax != NULL ) *rmax =max; if ( rmean != NULL ) *rmean=mean; if ( rstdd != NULL ) *rstdd=stdd; return(0); } double estimate_skysigma_naive(double *rawdata,int k,double sky,double smm,double spp) { double sp,sp2,ssigma,w; int i,j; sp=0.0;sp2=0.0;j=0; for ( i=0 ; i=nhist ) continue; histo[j]+=1.0; } /* for ( i=0 ; ihisto[j] ) j=i; } hmx=histo[j]; nvar=4; amatrix=matrix_alloc(nvar); bvector=vector_alloc(nvar); for ( i=0 ; i 0.0 ) x0=x1; else x0=x2; sky_fit=x0; xmx=((fp*x0+fq)*x0+fr)*x0+fs; sigr=-((6*fp*x0+2*fq)/xmx); skysigma=1/sqrt(sigr); if ( rsky != NULL ) *rsky =sky_fit; if ( rskysigma != NULL ) *rskysigma=skysigma; return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fits_stat_sky(fitsimage *img,double stddev,double *rsky,double *rskysigma) { int i,j,k,sx,sy; double *rawdata,sky,skysigma; sx=img->sx,sy=img->sy; rawdata=(double *)malloc(sizeof(double)*sx*sy); for ( i=0,k=0 ; idata[i][j]; k++; } } fits_stat_raw_sky_skysigma(rawdata,sx*sy,stddev,&sky,&skysigma); free(rawdata); if ( rsky != NULL ) *rsky =sky; if ( rskysigma != NULL ) *rskysigma=skysigma; return(0); } double fits_stat_median(fitsimage *img) { int i,j,k,sx,sy; double *rawdata,med; sx=img->sx,sy=img->sy; rawdata=(double *)malloc(sizeof(double)*sx*sy); for ( i=0,k=0 ; idata[i][j]; k++; } } med=median(rawdata,sx*sy); free(rawdata); return(med); } int fits_stat_background(fitsimage *img,int nbx,int nby,point **pdsky,point **pdsigma,double stddev) { int i,j,k,sx,sy; int ii,jj,in,jn,imin,imax,jmin,jmax,tn; double *rdata,x,y,val,sig; sx=img->sx,sy=img->sy; for ( i=0 ; idata[ii][jj]; } } fits_stat_raw_sky_skysigma(rdata,tn,stddev,&val,&sig); free(rdata); y=0.5*(double)(imax+imin-1); x=0.5*(double)(jmax+jmin-1); pdsigma[i][j].x=pdsky[i][j].x=x/(double)sx; pdsigma[i][j].y=pdsky[i][j].y=y/(double)sy; pdsky [i][j].value=val; pdsigma[i][j].value=sig; pdsky [i][j].weight=1.0; pdsigma[i][j].weight=1.0; } } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fits_stat_sky_like_isis(fitsimage *img,double stddev,double *rsky,double *rskysigma) { int i,j,k,sx,sy; double *rawdata,sky,skysigma; sx=img->sx,sy=img->sy; rawdata=(double *)malloc(sizeof(double)*sx*sy); for ( i=0,k=0 ; idata[i][j]; k++; } } sky=median(rawdata,sx*sy); for ( i=0 ; idata==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); rawdata=(double *)tensor_alloc_1d(double,sx*sy); bqc=(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); mask=(char **)tensor_alloc_2d(char,sx,sy); biquad_coeff(img->data,sx,sy,bqc,NULL); for ( i=0 ; irlevel*sct ) mask[i][j]=-1; } } if ( k==0 ) fits_mask_expand_false(mask,sx,sy,1,-1,-1,1); } for ( i=0,n=0 ; idata[i][j],n++; } } *rskysigma=med*1.8498; *rsky=median(rawdata,n); fits_mask_free(mask); tensor_free(bqc); tensor_free(rawdata); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/link/0000755000175000017500000000000012772016355013007 5ustar apalapalfitsh-0.9.2/src/link/link.h0000644000175000017500000000076410667340126014121 0ustar apalapal/*****************************************************************************/ /* link.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Common header file for including 'linkpoint.h' and 'linkblock.h' */ /*****************************************************************************/ #ifndef __LINK_H_INCLUDED #define __LINK_H_INCLUDED 1 #include "linkpoint.h" #include "linkblock.h" #endif fitsh-0.9.2/src/link/linkblock.c0000644000175000017500000000310011116251607015105 0ustar apalapal/*****************************************************************************/ /* linkblock.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to linking/connecting rectangular-shaped blocks */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include "linkblock.h" static int linkblock_sort(const void *p1,const void *p2) { if ( ((linkblock *)p1)->x1 < ((linkblock *)p2)->x1 ) return(-1); else return(1); } int linkblock_connect(linkblock *lblocks,int nlblock) { int i,j,y1,y2,x2; linkblock *lc,*ln,*wc,*wn,*ww; if ( lblocks==NULL || nlblock<=0 ) return(1); for ( i=0 ; ix2; y1=lc->y1; y2=lc->y2; for ( j=i+1 ; lblocks[j].x1y2y1 ) continue; for ( wn=ln ; wn->prev != NULL ; ) wn=wn->prev; for ( ww=wn ; ww != NULL ; ww=ww->next ) { if ( ww==lc ) break; } if ( ww != NULL ) continue; for ( wc=lc ; wc->next != NULL ; ) wc=wc->next; wc->next=wn; wn->prev=wc; } } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/link/linkpoint.c0000644000175000017500000001750012771507534015170 0ustar apalapal/*****************************************************************************/ /* linkpoint.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to linking points (see linkpoint.h for a more detailed */ /* description). This simple standalone library is the core of some */ /* sophisticated object detection algorithms. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006, 2007; Pal, A. (apal@szofi.elte.hu). */ /*****************************************************************************/ #include #include #include #include #include "linkpoint.h" /*****************************************************************************/ static void *link_alloc(int typesize,int sx,int sy) { int tsize,psize,bsize,cd,cb,snext,pnext; int i,j,arr[2],rank; void *ret,**pret; rank=2; arr[0]=sx,arr[1]=sy; psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { bsize=bsize*arr[i]; psize+=bsize; } psize=psize*sizeof(void *); tsize=psize+typesize*bsize*arr[0]; pret=(void **)malloc(tsize); if ( pret==NULL ) return(NULL); psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { cd=arr[i]; if ( i>1 ) snext=sizeof(void *); else snext=typesize; cb=cd*bsize; pnext=psize+cb; for ( j=0 ; j=sy ) k1=sy-1; l1=j+1; if ( l1>=sx ) l1=sx-1; if ( ! exclude_mask ) { wmin=wmax=arr[i][j]; n=0; maxx=minx=j; maxy=miny=i; if ( mask != NULL ) { for ( k=k0 ; k<=k1 ; k++ ) { for ( l=l0 ; l<=l1 ; l++ ) { if ( mask[k][l] ) continue; w=arr[k][l]; if ( w>wmax ) wmax=w,maxx=l,maxy=k; else if ( wwmax ) wmax=w,maxx=l,maxy=k; else if ( wwmax ) wmax=w,maxx=l,maxy=k; else if ( wwmax ) wmax=w,maxx=l,maxy=k; else if ( w0 ) { if ( flag>0 ) { *rnx=maxx; *rny=maxy; } else { *rny=minx; *rny=miny; } } return(n); } int linkpoint_mask_same_group(linkpoint **lparr,int sx,int sy,int j,int i) { int k0,k,k1,l0,l,l1,mx,my; int msi,msd,cmask,rmask; k0=i-1;msi=0x01;if ( k0<0 ) k0=0,msi=0x08; l0=j-1;msd=0; if ( l0<0 ) l0=0,msd=1; k1=i+1; if ( k1>=sy ) k1=sy-1; l1=j+1; if ( l1>=sx ) l1=sx-1; rmask=0; mx=lparr[i][j].mx; my=lparr[i][j].my; for ( k=k0 ; k<=k1 ; k++,msi<<=3 ) { for ( l=l0,cmask=msi<ymin,imax=lr->ymax; jmin=lr->xmin,jmax=lr->xmax; if ( imin>imax ) i=imin,imin=imax,imax=i; if ( jmin>jmax ) j=jmin,jmin=jmax,jmax=j; } if ( imin<0 ) imin=0; if ( imax>=sy ) imax=sy-1; if ( jmin<0 ) jmin=0; if ( jmax>=sx ) jmax=sx-1; lparr=(linkpoint **)link_alloc(sizeof(linkpoint),sx,sy); for ( i=0 ; i0 ) { lparr[i][j].nx=nx; lparr[i][j].ny=ny; } /* lparr[i][j].mx=lparr[i][j].my=-1; */ } } return(lparr); } int linkpoint_get_link_end(linkpoint **lparr,int nx,int ny,int *rmx,int *rmy) { int wx,wy; if ( lparr[ny][nx].nx < 0 || lparr[ny][nx].ny < 0 ) return(-1); while ( lparr[ny][nx].nx != nx || lparr[ny][nx].ny != ny ) { wx=lparr[ny][nx].nx, wy=lparr[ny][nx].ny; nx=wx, ny=wy; } *rmx=nx, *rmy=ny; return(0); } int linkpoint_is_same_endpoint(linkpoint **lparr,int x1,int y1,int x2,int y2) { int mx1,my1,mx2,my2; if ( linkpoint_get_link_end(lparr,x1,y1,&mx1,&my1) < 0 ) return(-1); else if ( linkpoint_get_link_end(lparr,x2,y2,&mx2,&my2) < 0 ) return(-1); else if ( mx1==mx2 && my1==my2 ) return(1); else return(0); } int linkpoint_reconnect(linkpoint **lparr,int sx,int sy) { int i,j,mx,my; if ( lparr==NULL || sx<=0 || sy<=0 ) return(1); for ( i=0 ; i=sy ) k1=sy-1; for ( j=0 ; j=sx ) l1=sx-1; nngh=0; nsgn=0; for ( k=k0 ; k<=k1 ; k++ ) { for ( l=l0 ; l<=l1 ; l++ ) { if ( lparr[k][l].nx<0 || lparr[k][l].ny<0 ) continue; nngh++; if ( lparr[k][l].mx==wx && lparr[k][l].my==wy ) nsgn++; } } lrarr[i][j].nngh=nngh-1; lrarr[i][j].nsgn=nsgn-1; } } return(lrarr); } int linkreference_free(linkreference **arr) { link_free((void *)arr); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/link/linkblock.h0000644000175000017500000000175010667340126015130 0ustar apalapal/*****************************************************************************/ /* linkblock.h */ /*****************************************************************************/ #ifndef __LINKBLOCK_H_INCLUDED #define __LINKBLOCK_H_INCLUDED 1 typedef struct linkblock linkblock; struct linkblock { int x1,y1; int x2,y2; linkblock *next,*prev; int id,flag; }; /* linkblock_connect(): Connects intersecting blocks of the array 'lblocks'. After this call, the structure elements 'next' and 'prev' are set pointing to the next and previous connected elements (inside this array). Note that the elements of the array 'lblocks' are presumably re-ordered; the structure members 'id' are set before all sortings to ascending order (begining with zero) but the pointers ('next', 'prev') points inside the sorted array. */ int linkblock_connect(linkblock *lblocks,int lnblock); #endif fitsh-0.9.2/src/link/Makefile.in0000644000175000017500000000067011657564440015063 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ CFLAGS=@CFLAGS@ all: link.a floodfill.o .PHONY: all clean link.a: linkpoint.o linkblock.o $(AR) src link.a linkpoint.o linkblock.o floodfill.o: floodfill.c floodfill.h $(CC) $(CFLAGS) -c floodfill.c linkpoint.o: linkpoint.c linkpoint.h link.h $(CC) $(CFLAGS) -c linkpoint.c linkblock.o: linkblock.c linkblock.h link.h $(CC) $(CFLAGS) -c linkblock.c clean: rm -f *.o *.a fitsh-0.9.2/src/link/linkpoint.h0000644000175000017500000001567411063041710015165 0ustar apalapal/*****************************************************************************/ /* linkpoint.h */ /*****************************************************************************/ #ifndef __LINKPOINT_H_INCLUDED #define __LINKPOINT_H_INCLUDED 1 /*****************************************************************************/ typedef struct { short nx,ny; /* indices of the next point in the link: */ /* - differs from the array index if normal */ /* - the same as the array index if extreme */ /* - negative if invalid */ short mx,my; /* index of the extreme point in the link */ } linkpoint; typedef struct { int mcnt; /* number of extreme link references */ int identifier; /* an identifier for the equivalence class */ short ncnt; /* number of next point references */ short nngh; /* number of valid neighbors */ short nsgn; /* number of neighbors within the same group */ /* (latter two include the point itself) */ short aux; /* auxiliary/temporary variable */ } linkreference; typedef struct { int xmin,xmax; int ymin,ymax; } linkrange; /*****************************************************************************/ /* linkpoint_local_extreme(): This function searches the local extreme value of the distribution 'arr' around the pixel (x,y). The array has the size of sx times sy. If the mask 'mask' is not NULL, the points where mask is non-zero are also excluded. The flag is positive if the extreme value is a maximum, otherwise the function searches for a minimum. The function returns the total number of points/pixels which were analyzed. This value is something between 0 and 9. If the exclude_mask parameter is non-zero the pixels (respecing to the set bits of exclude_mask) around (x,y) are excluded from the search. The coordinates of the pixel with the extreme value are returned in rnx and rny, if at least one point is investigated (i.e. the return value is positive), otherwise these values are unchanged. If an error occurs, the function returns a negative value. The mask values are related to the neighbors as follows: 0x001: ( x-1 , y-1 ) 0x002: ( x , y-1 ) 0x004: ( x+1 , y-1 ) 0x008: ( x-1 , y ) 0x010: ( x , y ) 0x020: ( x+1 , y ) 0x040: ( x-1 , y+1 ) 0x080: ( x , y+1 ) 0x100: ( x+1 , y+1 ) */ int linkpoint_local_extreme(double **arr,int ox,int oy,int sx,int sy,char **mask, int x,int y,int flag,int exclude_mask,int *rnx,int *rny); /* linkpoint_mask_same_group(): This function creates and returns an exclusion mask based on the linkpoint array 'lparr' (with the size of sx times sy) for the given pixel (x,y). The points with invalid (negative) values of nx and ny and points which are in the same group as the pixel (x,y) are included in the mask. */ int linkpoint_mask_same_group(linkpoint **lparr,int sx,int sy,int x,int y); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* linkpoint_create(): Creates a two dimensional (dynamically allocated) array of points with the type of 'linkpoint' holding the information about the convergence to local maximums ('flag' is positive) or local minimums ('flag' is negative). The elements nx and ny in the structure 'linkpoint' are set, these are the array indices of the largest/smallest neighbour. The optional parameter 'lr' can be used to specify a region inside the rectangle [0,sx-1] x [0,sy-1] where this maximum/minimum search should be performed. Thee optional argument 'mask' may contain a _bad_ mask of points which should not be taken into account (bad means the array element mask[i][j] should be non-zero if this point wants to be rejected). Both 'lr' and 'mask' can be NULL. If the linking was successful, the function returns an array of 'sx' times 'sy' of linkpoints with the desired information, otherwise (when an error occurs) it returns NULL (even when 'flag' is zero: it must be any arbitrary positive or negative integer, depending on the request, but not zero). */ linkpoint ** linkpoint_create(double **arr,int sx,int sy,linkrange *lr, char **mask,int flag); /* linkpoint_get_link_end(): Gets the endpoint of the pixel (nx,ny) based on the link array 'lparr'. If there is an endpoint, the function returns 0, otherwise it returns -1. */ int linkpoint_get_link_end(linkpoint **lparr, int nx,int ny,int *rmx,int *rmy); /* linkpoint_is_same_endpoint(): This function returns a positive value if the endpoints of the links defined by (x1,y1) and (x2,y2) are the same, otherwise, if the linkpoints are valid, the function returns 0; in the other cases (i.e. when any of the points are invalid), the function returns a negative value. The important role of this function is to check this property without the usage of the mx and my fields (i.e. if these are set, two points defines the same link if and only if their mx and my values are the same). */ int linkpoint_is_same_endpoint(linkpoint **lparr, int x1,int y1,int x2,int y2); /* linkpoint_reconnect(): This function sets the linkpoint structure elements and mx and my, which are the array indices of the local maximum/minimum can be reached via the links of nx/ny points. The array 'lparr' should be (somehow) preinitialized, i.e. the nx and ny values should be proper ones. Generally this initialization is done by linkpoint_create(). Note that this and the previous functions are disjoint in the manner that the former sets only the nx and ny elements and sets mx and my to (-1) while the latter does not affect the values nx and ny, only sets mx and my. */ int linkpoint_reconnect(linkpoint **lparr,int sx,int sy); /* linkpoint_free(): Releases the array 'arr' which was dynamically allocated and returned by a previous call of linkpoint_create(). This function always return zero. */ int linkpoint_free(linkpoint **arr); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* linkreference_create(): This function creates a dynamically allocated array of reference counts of the linkpoint array 'lparr' (which has a size of sx times sy). The linkpoint array should be a reconnected one, i.e. the mx and my values should be initialized by linkpoint_reconnect(). All values (ncnt, mcnt, nngh and nsgn) are set for a valid (non-masked) point. For an invalid one (where nx or ny is negative), all values are set to a negative value. */ linkreference **linkreference_create(linkpoint **lparr,int sx,int sy); /* linkreference_free(): Releases the array 'arr' which was dynamically allocated and returned by a previous call of linkreference_create(). This function always return zero.*/ int linkreference_free(linkreference **arr); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/link/floodfill.h0000644000175000017500000000211410667340126015125 0ustar apalapal/*****************************************************************************/ /* floodfill.c */ /*****************************************************************************/ #ifndef __FLOODFILL_H_INCLUDED #define __FLOODFILL_H_INCLUDED 1 /* floodfill(): Fills an area. The start point of the flood-filling is (x0,y0). The functions getp() and putp() should read and set the pixel value located at (x,y). The function getp() should return 0, if the point (x,y) is empty, otherwise it should return a nonzero value. The putp() function should fill the pixel located at (x,y) and store the information somehow that this pixel has been filled (so, invoked with this (x,y) point, getp() should return a nonzero value). If getp(...,x0,y0) was nonzero, the function floodfill() wouldn't do anything. The optional argument 'param' is always passed to the functions getp() and putp() at all invocations. */ int floodfill( int x0,int y0, int (*getp)(void *param,int x,int y), void (*putp)(void *param,int x,int y), void *param); #endif fitsh-0.9.2/src/link/floodfill.c0000644000175000017500000000665411116251670015130 0ustar apalapal/*****************************************************************************/ /* floodfill.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for filling areas. */ /* (c) 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in floodfill.h */ /*****************************************************************************/ #include #include #include #include #include "floodfill.h" /*****************************************************************************/ typedef struct { int x1,x2; int y,dy; } linesegment; #define MAXDEPTH 64 #define PUSH(XL,XR,Y,DY) \ if ( spx1=XL;sp->x2=XR;sp->y=Y;sp->dy=DY; sp++; } #define POP(XL,XR,Y,DY) \ { sp--;XL=sp->x1;XR=sp->x2;Y=sp->y+(DY=sp->dy); } int floodfill_old(int x,int y,int (*getp)(void *,int,int),void (*putp)(void *,int,int),void *param) { int left,x1,x2,dy,skip; linesegment stack[MAXDEPTH],*sp; sp=stack; if ( getp(param,x,y) ) return(0); PUSH(x,x,y,1); PUSH(x,x,y+1,-1); left=0; while ( sp>stack ) { POP(x1,x2,y,dy); for ( x=x1 ; ! getp(param,x,y) ; x-- ) putp(param,x,y); if( x >= x1 ) skip=1; else skip=0; if ( ! skip ) { left=x+1; if ( leftx2+1 ) { PUSH(x2+1,x-1,y,-dy); } } skip=0; for( x++ ; x <= x2 && getp(param,x,y) ; x++ ) ; left=x; } while ( x<=x2 ); } return(0); } typedef struct { int x; int y; } point; #define STACKBLOCK 64 int floodfill(int x,int y,int (*getp)(void *,int,int),void (*putp)(void *,int,int),void *param) { point stack_static[STACKBLOCK],*stack_dynamic,*stack; int bl,bh,px,py,is_dec,sp,mxsp; if ( getp(param,x,y) ) return(0); stack=stack_static; stack_dynamic=NULL; sp=0;mxsp=STACKBLOCK; bl=bh=0; is_dec=1; while ( 1 ) { if ( is_dec ) { while ( ! getp(param,x,y) ) x--; } putp(param,x,y); if ( ! getp(param,x,y-1) ) { if ( bl==0 ) { bl=1; stack[sp].x=x,stack[sp].y=y-1,sp++; if ( sp==mxsp ) { mxsp+=STACKBLOCK; if ( sp==STACKBLOCK ) { stack_dynamic=(point *)malloc(sizeof(point)*mxsp); memcpy(stack_dynamic,stack_static,sizeof(point)*sp); stack=stack_dynamic; } else { stack_dynamic=(point *)realloc(stack_dynamic,sizeof(point)*mxsp); stack=stack_dynamic; } } } } else bl=0; if ( ! getp(param,x,y+1) ) { if ( bh==0 ) { bh=1; stack[sp].x=x,stack[sp].y=y+1,sp++; if ( sp==mxsp ) { mxsp+=STACKBLOCK; if ( sp==STACKBLOCK ) { stack_dynamic=(point *)malloc(sizeof(point)*mxsp); memcpy(stack_dynamic,stack_static,sizeof(point)*sp); stack=stack_dynamic; } else { stack_dynamic=(point *)realloc(stack_dynamic,sizeof(point)*mxsp); stack=stack_dynamic; } } } } else bh=0; if ( ! getp(param,x+1,y) ) { x++; is_dec=0; } else { if ( sp==0 ) break; sp--,px=stack[sp].x,py=stack[sp].y; if ( y #include #include #include #include #include #include #include "fitsh.h" #include "fitsmask.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "magnitude.h" #include "math/poly.h" #include "common.h" #include "kernel.h" #include "fiphot.h" /*****************************************************************************/ int read_input_star_list(FILE *fr,photstar **rps,int *rnp,colread *col,int zoom) { photstar *ps; int np,n,i,k,cr0,cra,cda; char *buff,*cmd[64],*id; double x,y,r0,ra,da,ref_mag,ref_col,ref_err; apgeom *inaps; int ninap,use_ref; ps=NULL;np=0; buff=NULL; if ( zoom<1 ) zoom=1; while ( ! feof(fr) ) { if ( buff != NULL ) free(buff); buff=freadline(fr); if ( buff==NULL ) break; remove_newlines_and_comments(buff); if ( strlen(buff)==0 ) continue; n=tokenize_spaces(buff,cmd,63); if ( col->colx>=n || col->coly>=n ) continue; sscanf(cmd[col->colx],"%lg",&x); sscanf(cmd[col->coly],"%lg",&y); if ( ! ( isfinite(x) && isfinite(y) ) ) continue; inaps=NULL; ninap=0; for ( i=0 ; col->colap[i]>=0 ; i+=3 ) { cr0=col->colap[i], cra=col->colap[i+1], cda=col->colap[i+2]; if ( cr0>=n ) continue; r0=ra=da=0.0; k=sscanf(cmd[cr0],"%lg:%lg:%lg",&r0,&ra,&da); if ( k<1 ) continue; if ( ! isfinite(r0) || ! isfinite(ra) || ! isfinite(da) ) continue; inaps=(apgeom *)realloc(inaps,sizeof(apgeom)*(ninap+1)); inaps[ninap].apgeom_type=APGEOM_TYPE_CIRCULAR; inaps[ninap].r0=r0; if ( cra>=0 && cda>=0 ) { if ( cra=2 ) inaps[ninap].ra=ra; else inaps[ninap].ra=0.0; if ( k>=3 ) inaps[ninap].da=da; else inaps[ninap].da=0.0; } inaps[ninap].r0 *= (double)zoom; inaps[ninap].ra *= (double)zoom; inaps[ninap].da *= (double)zoom; ninap++; } if ( 0<=col->colid && col->colidcolid]; else id=NULL; if ( 0<=col->colmag && col->colmagcolmag],"%lg",&ref_mag); else ref_mag=0.0,use_ref=0; if ( 0<=col->colcol && col->colcolcolcol],"%lg",&ref_col); else ref_col=0.0; if ( 0<=col->colerr && col->colerrcolerr],"%lg",&ref_err); else ref_err=0.0; ps=(photstar *)realloc(ps,sizeof(photstar)*(np+1)); ps[np].x=(double)zoom*(x); ps[np].y=(double)zoom*(y); ps[np].inaps=inaps; ps[np].ninap=ninap; ps[np].use_ref=use_ref; ps[np].ref_mag=ref_mag; ps[np].ref_col=ref_col; ps[np].ref_err=ref_err; ps[np].fluxes=NULL; ps[np].rfflux=NULL; if ( id==NULL ) ps[np].id=NULL; else ps[np].id=strdup(id); np++; }; *rps=ps, *rnp=np; return(0); } int read_raw_photometry(FILE *fr,photstar **rps,int *rnp) { photstar *ps; photflux *rfflux; int np,t,n,i,r,flag; char *buff,**cmd,*id; double x,y,ref_mag,ref_col; apgeom *inaps; ps=NULL;np=0; buff=NULL;cmd=NULL; while ( ! feof(fr) ) { if ( cmd != NULL ) { free(cmd);cmd=NULL; } if ( buff != NULL ) { free(buff);buff=NULL; } buff=freadline(fr); if ( buff==NULL ) break; remove_newlines_and_comments(buff); if ( strlen(buff)==0 ) continue; cmd=tokenize_spaces_dyn(buff); for ( t=0 ; cmd[t] != NULL ; ) t++; if ( t<12 ) continue; id=cmd[0]; if ( sscanf(cmd[1],"%lg",&x)<1 ) continue; if ( sscanf(cmd[2],"%lg",&y)<1 ) continue; if ( ! ( isfinite(x) && isfinite(y) ) ) continue; if ( sscanf(cmd[3],"%d",&n)<1 ) continue; if ( t<6+n*6 ) continue; ps=(photstar *)realloc(ps,sizeof(photstar)*(np+1)); ps[np].x=x, ps[np].y=y; ps[np].n=ps[np].ninap=n; if ( sscanf(cmd[4],"%lg",&ref_mag)==1 ) { ps[np].use_ref=1; ps[np].ref_mag=ref_mag; } else { ps[np].use_ref=0; ps[np].ref_mag=0.0; } if ( sscanf(cmd[5],"%lg",&ref_col)==1 ) ps[np].ref_col=ref_col; else ps[np].ref_col=0.0; inaps=(apgeom *)malloc(sizeof(apgeom)*n); for ( i=0 ; iid_len ) id_len=j; } sprintf(idf,"%%-%ds ",id_len); sprintf(ndf,"%%%dd ",id_len); *rid_len=id_len; return(0); } int write_output_star_list(FILE *fw,photstar *ps,int np) { int i,id_len; char id_format[8],nd_format[8]; if ( np==0 ) return(0); get_id_format_parameters(ps,np,&id_len,id_format,nd_format); for ( i=0 ; i0.0 ) { fprintf(fw," %6.3f",ps[i].optimal.r0); if ( ps[i].optimal.ra>0.0 ) { fprintf(fw," %6.3f %6.3f",ps[i].optimal.ra,ps[i].optimal.da); } } fprintf(fw,"\n"); } return(0); } /*****************************************************************************/ static int photometry_status_letter(photflux *pf) { if ( ( pf->rbad>0 && pf->rbad>pf->rign ) || pf->atot==0 || pf->flux <= 0.0 ) return('X'); else if ( pf->rign>0 ) return('C'); else return('G'); } int photometry_status(char *buff,photflux *pf) { /* "X-bfhcsio-CCC/BBB/TTT-GGG/TTT", length: 25 */ sprintf(buff,"----------%.3d/%.3d/%.3d-%.3d/%.3d",pf->rign,pf->rbad,pf->rtot,pf->abad,pf->atot); if ( pf->flag & MASK_NOBACKGROUND ) buff[2]='b'; if ( pf->flag & MASK_FAULT ) buff[3]='f'; if ( pf->flag & MASK_HOT ) buff[4]='h'; if ( pf->flag & MASK_COSMIC ) buff[5]='c'; if ( pf->flag & MASK_SATURATED ) buff[6]='s'; if ( pf->flag & MASK_INTERPOLATED ) buff[7]='i'; if ( pf->flag & MASK_OUTER ) buff[8]='o'; buff[0]=photometry_status_letter(pf); return(0); } int photometry_short_status(char *buff,photflux *pf) { buff[0]=photometry_status_letter(pf); buff[1]=0; return(0); } int write_photometry(FILE *fw,photstar *ps,int np,char *ofxy,char *ofph, spatialgain *sg,char *nanstring,char *serialstring,int sx,int sy) { int i,j,id_len,serial_len,fchar,ok_magn,ok_flux,ok_back; char id_format[8],nd_format[8],buff[128],*f; double gain; photflux * pf; if ( np==0 ) return(0); get_id_format_parameters(ps,np,&id_len,id_format,nd_format); if ( serialstring==NULL ) { serial_len=1; serialstring="-"; } else serial_len=strlen(serialstring); if ( is_comment ) { fchar='#'; for ( f=ofxy ; *f && *f != ',' ; f++ ) { switch ( *f ) { case 'X': fprintf(fw,"%c X Coord. ",fchar);break; case 'Y': fprintf(fw,"%c Y Coord. ",fchar);break; case 'S': fprintf(fw,"%c Serial ",fchar); for ( i=8 ; iorder,sg->coeff, 0.5*(double)sx,0.5*(double)sy,0.5*(double)sx); if ( sg->vmin > 0 && gain < sg->vmin ) gain=sg->vmin; else if ( gain < 0.0 ) gain=0.0; for ( f=ofxy ; *f && *f != ',' ; f++ ) { switch ( *f ) { case 'X': fprintf(fw,"%11.3f ",ps[i].x); break; case 'Y': fprintf(fw,"%11.3f ",ps[i].y); break; case 'S': fprintf(fw,"%8s ",serialstring); break; case 'I': if ( ps[i].id==NULL ) fprintf(fw,nd_format,i+1); else fprintf(fw,id_format,ps[i].id); break; case '-': fprintf(fw," - ");break; } } for ( j=0 ; jflag & MASK_NOBACKGROUND); ok_flux=ok_back; ok_magn=(ok_back && pf->flux>0.0 ); if ( *f=='-' ) fprintf(fw," - "); else if ( *f=='B' || *f=='b' ) { if ( ! ok_back ) fprintf(fw,"%11s ",nanstring); else if ( *f=='B' ) fprintf(fw,"%11.2f ",pf->bgmedian); else fprintf(fw,"%11.2f ",pf->bgsigma); } else if ( *f=='S' ) { photometry_status(buff,pf); fprintf(fw,"%s ",buff); } else if ( *f=='s' ) { photometry_short_status(buff,pf); fprintf(fw,"%s ",buff); } else if ( pf->rignrbad && pf->rbad==pf->rtot ) fprintf(fw,"%11s ",nanstring); else { switch ( *f ) { case 'M': if ( ok_magn ) fprintf(fw,"%11.5f ",pf->mag); else fprintf(fw,"%11s ",nanstring); break; case 'm': if ( ok_magn ) fprintf(fw,"%11.5f ",pf->magerr); else fprintf(fw,"%11s ",nanstring); break; case 'F': case 'A': if ( ok_flux ) fprintf(fw,"%11.2f ",pf->flux); else fprintf(fw,"%11s ",nanstring); break; case 'f': case 'a': if ( ok_flux ) fprintf(fw,"%11.2f ",pf->fluxerr); else fprintf(fw,"%11s ",nanstring); break; case 'X': if ( ok_flux ) fprintf(fw,"%11.3f ",pf->cntr_x); else fprintf(fw,"%11s ",nanstring); break; case 'x': if ( ok_flux ) fprintf(fw,"%11.3f ",pf->cntr_x_err); else fprintf(fw,"%11s ",nanstring); break; case 'Y': if ( ok_flux ) fprintf(fw,"%11.3f ",pf->cntr_y); else fprintf(fw,"%11s ",nanstring); break; case 'y': if ( ok_flux ) fprintf(fw,"%11.3f ",pf->cntr_y_err); else fprintf(fw,"%11s ",nanstring); break; case 'W': if ( ok_flux && 0.0cntr_width ) fprintf(fw,"%11.3f ",pf->cntr_width); else fprintf(fw,"%11s ",nanstring); break; case 'w': if ( ok_flux && 0.0cntr_width ) fprintf(fw,"%11.3f ",pf->cntr_w_err); else fprintf(fw,"%11s ",nanstring); break; case 'D': if ( ok_flux && 0.0cntr_width ) fprintf(fw,"%11.3f ",pf->cntr_w_d); else fprintf(fw,"%11s ",nanstring); break; case 'K': if ( ok_flux && 0.0cntr_width ) fprintf(fw,"%11.3f ",pf->cntr_w_k); else fprintf(fw,"%11s ",nanstring); break; case 'E': if ( ok_flux ) fprintf(fw,"%11.2f ",pf->flux*gain); else fprintf(fw,"%11s ",nanstring); break; case 'e': if ( ok_flux ) fprintf(fw,"%11.2f ",pf->fluxerr*gain); else fprintf(fw,"%11s ",nanstring); break; default: fprintf(fw,"%11s ",nanstring); break; } } } } fprintf(fw,"\n"); } return(0); } int write_raw_photometry(FILE *fw,photstar *ps,int np,char *nanstring) { int i,j,id_len,n; char id_format[8],nd_format[8]; photflux *pf; double x,y; if ( np==0 ) return(0); get_id_format_parameters(ps,np,&id_len,id_format,nd_format); if ( is_comment ) { fprintf(fw,"# Raw photometry file, summarize all information which may required by \n"); fprintf(fw,"# photometry on subtracted images. Format is fixed, cannot be changed.\n"); fprintf(fw,"# Do not edit unless you exactly know what are you doing!\n"); } for ( i=0 ; iag.r0,pf->ag.ra,pf->ag.da); if ( pf->flag & 0x0100 ) fprintf(fw," %11g %11g 0x%04x",0.0,0.0,pf->flag); else fprintf(fw," %11g %11g 0x%04x",pf->flux,pf->fluxerr,pf->flag); } fprintf(fw,"\n"); } return(0); } /*****************************************************************************/ char *output_format_xy(char *oformat) { char *ofxy; int c; for ( ofxy=oformat ;*oformat && *oformat != ',' ; oformat++ ) { c=*oformat; if ( ! ( c=='X' || c=='Y' || c=='I' || c=='S' || c=='-' ) ) return(NULL); } return(ofxy); } char *output_format_ph(char *oformat) { char *ofph,*achr; int c; while ( *oformat && *oformat != ',' ) oformat++; if ( *oformat != ',' ) return(NULL); oformat++; achr="MmBbFfEeAaXxYyWwDKSs-"; for ( ofph=oformat ; *oformat && *oformat != ',' ; oformat++ ) { c=*oformat; if ( strchr(achr,c)==NULL ) return(NULL); } return(ofph); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ char *subtracted_format_xy(char *sformat) { char *sfxy; int c; for ( sfxy=sformat ;*sformat && *sformat != ',' ; sformat++ ) { c=*sformat; if ( ! ( c=='N' || c=='H' ) ) return(NULL); } return(sfxy); } char *subtracted_format_ph(char *sformat) { char *sfph; int c; while ( *sformat && *sformat != ',' ) sformat++; if ( *sformat != ',' ) return(NULL); sformat++; for ( sfph=sformat ;*sformat && *sformat != ',' ; sformat++ ) { c=*sformat; if ( ! ( c=='M' || c=='m' || c=='F' || c=='f' || c=='E' || c=='e' || c=='A' || c=='a' ) ) return(NULL); } return(sfph); } /*****************************************************************************/ int * create_col_ap_data(char *apcolpar) { int *colap; char *acp,*cmd[64]; int i,n,k,cr0,cra,cda,ncc; colap=NULL;ncc=0; if ( apcolpar==NULL ) { colap=(int *)malloc(sizeof(int)*1); colap[0]=-1; return(colap); } else { acp=strdup(apcolpar); n=tokenize_char(acp,cmd,',',63); for ( i=0 ; i0 ) colap[3*ncc+1]=cra-1; else colap[3*ncc+1]=-1; if ( cda>0 ) colap[3*ncc+2]=cda-1; else colap[3*ncc+2]=-1; ncc++; } colap[3*ncc]=-1; free(acp); return(colap); } } static int aperture_definition_create_polygon_regular(double **polypoints,int *npolypoint,double requiv,int nvertex,double alpha) { double *poly,r; int i; r=requiv*sqrt((2*M_PI/(double)nvertex)/sin(2*M_PI/(double)nvertex)); alpha=alpha*M_PI/180.0; poly=(double *)malloc(sizeof(double)*2*nvertex); for ( i=0 ; iapgeom_type=APGEOM_TYPE_CIRCULAR; ap->r0=r0; ap->ra=ra; ap->da=da; return(0); } else { int i,n; char *cmd[8]; n=tokenize_char(apdef,cmd,':',63); if ( n != 3 ) return(1); ap->apgeom_type=APGEOM_TYPE_POLYGON; ap->r0_poly=NULL; ap->ra_poly=NULL; ap->da_poly=NULL; ap->nr0=0; ap->nra=0; ap->nda=0; for ( i=0 ; i<3 ; i++ ) { double *polypoints; int npolypoint; double requiv,alpha,dx,dy; int nvertex,r; if ( sscanf(cmd[i],"Q[%lg,%d,%lg]",&requiv,&nvertex,&alpha)==3 || sscanf(cmd[i],"regular[%lg,%d,%lg]",&requiv,&nvertex,&alpha)==3 ) r=aperture_definition_create_polygon_regular(&polypoints,&npolypoint,requiv,nvertex,alpha); else if ( ( sscanf(cmd[i],"T[%lg,%d,%lg,%lg]",&requiv,&nvertex,&dx,&dy)==4 || sscanf(cmd[i],"trail[%lg,%d,%lg,%lg]",&requiv,&nvertex,&dx,&dy)==4 ) && (nvertex%2)==0 ) r=aperture_definition_create_polygon_trail(&polypoints,&npolypoint,requiv,nvertex,dx,dy); else if ( ( memcmp(cmd[i],"P[",2)==0 || memcmp(cmd[i],"polygon[",8)==0 ) && cmd[i][strlen(cmd[i])-1]==']' ) r=aperture_definition_create_polygon(&polypoints,&npolypoint,cmd[i]); else return(1); if ( r ) return(1); if ( i==0 ) ap->r0_poly=polypoints,ap->nr0=npolypoint; else if ( i==1 ) ap->ra_poly=polypoints,ap->nra=npolypoint; else ap->da_poly=polypoints,ap->nda=npolypoint; } return(0); } } int create_input_ap_data(char *appar,apgeom **rinaps,int *rninap,int zoom) { apgeom *inaps; int ninap,n,i; if ( zoom<1 ) zoom=1; if ( appar==NULL ) { inaps=NULL; ninap=0; } else { int w; char *ap,*cmd[64]; ap=strdup(appar); w=0; for ( i=0 ; ap[i] ; i++ ) { if ( ap[i]=='[' ) w++; else if ( ap[i]==']' ) w--; else if ( ap[i]==',' && w==0 ) ap[i]=';'; } if ( w != 0 ) return(1); n=tokenize_char(ap,cmd,';',63); inaps=NULL;ninap=0; for ( i=0 ; iapgeom_type == APGEOM_TYPE_CIRCULAR ) { ap->r0 *= (double)zoom; ap->ra *= (double)zoom; ap->da *= (double)zoom; } } *rinaps=inaps; *rninap=ninap; return(0); } int check_apertures(photstar *ps,int np) { int i,j,ninap; double r0,ra,da; if ( ps==NULL || np<=0 ) return(0); ninap=ps[0].ninap; for ( i=1 ; i #include #include #include #include #include #ifndef HAVE_NO_FNMATCH_H #include #endif #include #include "longhelp.h" #include "fitsh.h" #include "io/scanarg.h" #include "io/iof.h" #include "io/tokenize.h" /*****************************************************************************/ #define FORMAT_FILE 1 #define FORMAT_KEYWORD 2 #define FORMAT_VALUE 3 #define FORMAT_COMMENT 4 #define ALTER_UPDATE 1 #define ALTER_APPEND 2 #define ALTER_DELETE 3 /*****************************************************************************/ typedef struct { char keyword[16]; int occurrence; char value[72]; char comment[72]; } alter; /*****************************************************************************/ char *reserved_keywords[]= { "SIMPLE", "EXTEND", "XTENSION", "NAXIS", "+NAXIS", "BITPIX", "END", NULL }; /*****************************************************************************/ char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int fprint_header_value(FILE *fw,fitsheader *hdr) { if ( hdr->vtype==FITS_VINT ) fprintf(fw,"%d",hdr->vint); else if ( hdr->vtype==FITS_VBOOLEAN ) { if ( hdr->vint ) fprintf(fw,"T"); else fprintf(fw,"F"); } else if ( hdr->vtype==FITS_VDOUBLE ) fprintf(fw,"%.15g",hdr->vdouble); else if ( hdr->vtype==FITS_VSTR ) fprintf(fw,"%s",hdr->vstr); return(0); } /*****************************************************************************/ int fprint_formatted_keyword(FILE *fw,char *sfbuff,char *name,char *keyw,int *format,fitsheader *hdr) { int f; for ( f=0 ; format[f]>=0 ; f++ ) { if ( f>0 ) { fprintf(fw," "); } switch ( format[f] ) { case FORMAT_FILE: fprintf(fw,sfbuff,name); break; case FORMAT_KEYWORD: fprintf(fw,"%-8s",keyw); break; case FORMAT_VALUE: if ( hdr==NULL ) { fprintf(fw,"NULL"); } else { fprint_header_value(fw,hdr); } break; case FORMAT_COMMENT: if ( hdr != NULL ) { fprintf(fw,"# %s",hdr->comment); } break; } } fprintf(fw,"\n"); return(0); } int is_any_wildcard(char *buff) { while ( *buff ) { if ( *buff=='[' || *buff==']' || *buff=='*' || *buff=='?' ) return(1); else buff++; }; return(0); } int fprint_keyword(FILE *fw,fitsheaderset *header,char *name,char *keyw,int *format,int namelen) { char sfbuff[16]; int n,j; fitsheader *hdr; sprintf(sfbuff,"%%-%ds",namelen); if ( ! is_any_wildcard(keyw) ) { n=fits_headerset_get_count(header,keyw); if ( n==0 ) { fprint_formatted_keyword(fw,sfbuff,name,keyw,format,NULL); } for ( j=0 ; jnhdr ; j++ ) { hdr=&header->hdrs[j]; #ifndef HAVE_NO_FNMATCH_H if ( ! fnmatch(keyw,hdr->name,0) ) #else if ( strcmp(keyw,hdr->name)==0 ) #endif { fprint_formatted_keyword(fw,sfbuff,name,hdr->name,format,hdr); n++; } } } if ( n>0 ) return(0); else return(1); } int read_header_values_from_file(FILE *fr,char *extension,char *name,char **getkwlist,FILE *fw,int *format,int namelen) { fits *img; fitsheaderset *header; int i,k,nkw,ret; char **cmd,*kwl; if ( getkwlist==NULL ) return(0); if ( extension==NULL ) { img=fits_create(); fits_read_header(fr,img); header=&img->header; } else { int i,x; img=fits_read(fr); if ( sscanf(extension,"%d",&x)<1 ) x=-1; if ( 0<=x && xnxtn ) { header=&img->xtns[x].header; } else { fitsheader *fh; int l,l0; header=NULL; l0=strlen(extension); for ( i=0 ; inxtn ; i++ ) { fh=fits_headerset_get_header(&img->xtns[i].header,"EXTNAME",0); if ( fh==0 || fh->vtype != FITS_VSTR ) continue; l=strlen(fh->vstr); while ( 0vstr[l-1]==' ' ) l--; if ( strncmp(fh->vstr,extension,l)==0 && l==l0 ) header=&img->xtns[i].header; } } } ret=0; for ( i=0 ; getkwlist[i] != NULL ; i++ ) { kwl=strdup(getkwlist[i]); remove_spaces(kwl); for ( k=0,nkw=1 ; kwl[k] ; k++ ) { if ( kwl[k]==',' ) nkw++; else kwl[k]=toupper((int)kwl[k]); } cmd=(char **)malloc(sizeof(char *)*(nkw+1)); tokenize_char(kwl,cmd,',',nkw+1); for ( k=0 ; kkeyword,sk); wa->occurrence=occurrence; if ( is_set ) { strcpy(wa->value,sv); strcpy(wa->comment,sc); } else { wa->value[0]=0; wa->comment[0]=0; } }; if ( ralters != NULL ) *ralters=alters; if ( rnalter != NULL ) *rnalter=nalter; return(0); } int alter_header_set(fitsheaderset *header,char *updatelist,int policy,int force) { alter *alters,*wa; int nalter,i,j,k,lv; char *scomment,*sv; double d; alter_get_alternations(updatelist,&alters,&nalter,1); if ( alters==NULL || nalter<=0 ) return(0); for ( i=0 ; icomment[0] ) scomment=wa->comment; else scomment=NULL; if ( alter_is_reserved_keyword(wa->keyword) ) { if ( ! force ) { fprintf(stderr,"Warning: altering reserved keyword '%s' is not allowed, skipping.\n",wa->keyword); continue; } else { fprintf(stderr,"Warning: altering reserved keyword '%s'.\n",wa->keyword); } } sv=wa->value; lv=strlen(sv); if ( strcasecmp(sv,"f")==0 || strcasecmp(sv,"false")==0 ) { fits_headerset_set_boolean(header,wa->keyword,policy,0,scomment); } else if ( strcasecmp(sv,"t")==0 || strcasecmp(sv,"true")==0 ) { fits_headerset_set_boolean(header,wa->keyword,policy,1,scomment); } else if ( sv[0]=='\'' && sv[lv-1]=='\'' ) { memmove(sv,sv+1,lv);lv--; sv[lv-1]=0,lv--; for ( j=0 ; jkeyword,policy,sv,scomment); } else { k=1; for ( j=0 ; jkeyword,policy,j,scomment); } else if ( sscanf(sv,"%lg",&d)==1 ) { fits_headerset_set_double(header,wa->keyword,policy,d,scomment); } else { fits_headerset_set_string(header,wa->keyword,policy,sv,scomment); } } /*fprintf(stderr,"\"%s\"=\"%s\" [%s]\n",sk,sv,sc);*/ }; return(0); } int alter_header_delete(fitsheaderset *header,char *deletelist,int force) { alter *alters,*wa; int nalter,i,n; alter_get_alternations(deletelist,&alters,&nalter,0); if ( alters==NULL || nalter<=0 ) return(0); for ( i=0 ; ikeyword) ) { if ( ! force ) { fprintf(stderr,"Warning: deleting reserved keyword '%s' is not allowed, skipping.\n",wa->keyword); continue; } else { fprintf(stderr,"Warning: deleting reserved keyword '%s'.\n",wa->keyword); } } if ( wa->occurrence>0 ) { fits_headerset_delete(header,wa->keyword,wa->occurrence-1); } else if ( wa->occurrence<0 ) { n=fits_headerset_get_count(header,wa->keyword); fits_headerset_delete(header,wa->keyword,n+wa->occurrence); } else { fits_headerset_delete_all(header,wa->keyword); } }; return(0); } int alter_header_values(fitsheaderset *header,char **setkwlist,int force) { int i,action; char *kw; if ( setkwlist==NULL ) return(0); action=0; for ( i=0 ; setkwlist[i] != NULL ; i++ ) { if ( setkwlist[i][0]=='-' ) { action=alter_get_action(setkwlist[i]); if ( action<0 ) return(-1); /* it's incosistency! */ } else { kw=setkwlist[i]; switch ( action ) { case ALTER_UPDATE: alter_header_set(header,kw,FITS_SH_FIRST,force); break; case ALTER_APPEND: alter_header_set(header,kw,FITS_SH_ADD,force); break; case ALTER_DELETE: alter_header_delete(header,kw,force); break; }; } } return(0); } /*****************************************************************************/ int fprint_fiheader_usage(FILE *fw) { fprintf(fw, "Usage:\tfiheader [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[in.fits [-o out.fits|-w|--rewrite]] | [in1.fits [in2.fits ...]]\n"); fprintf(fw, "Read header/keyword values:\n" "\t[--get|--read [,,...]] [--get|--read ...]\n" "\t[-F|--format file[name],keyword,value,comment]\n"); fprintf(fw, "Altering keyword values:\n" "\t[--set|--update =[/comment][,=...,...]]\n" "\t[--append =value[/comment][,=...,...]]\n" "\t[--delete [][,,...]]\n" "\t[--force-alter-reserved-keywords]\n"); fprintf(fw, "Notes:\n" " - If a non-existent keyword is specified for --get|--read, it value is\n" " going to be the string \"NULL\" (w/o quotation), and the program will\n" " return with an exit status (errorlevel) of 2. Even if other specified\n" " keywords are exist and their values have been written properly!\n" " - Altering and reading keyword values at the same time is not permitted.\n"); fprintf(fw, " - If header values are altered and only one filename has been specified,\n" " the altered FITS file will be written to stdout or into file given by -o.\n" " This output file can be the same as the original one, and --rewirte is also\n" " allowed.\n" " - If header values are altered and more than one filename are specified, the\n" " same updating schema is used for all files (which are replaced sequentially\n" " by the updated ones).\n") ; return(0); } longhelp_entry fiheader_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-i, --input ", "Name of the input FITS image file." }, { "-o, --output ", "Name of the output FITS image file (can be the same as the input " "image file)." }, { "Read keyword values:", NULL }, { "-g, --get, --read ,...", "List of keywords to get from FITS header." }, { "-F, --format ", "Format of the output, space separated list of the arguments " "\"filename\", \"keyword\", \"value\" or \"comment\", in the " "desired order." }, { "-x, --extension ", "Read keyword values from the given extension." }, { "Note that shell wildcard character patterns can be used in the " "keyword specifications.", NULL }, { "",NULL }, { "Altering FITS headers:", NULL }, { "-s, --set, --update =[/],...", "List of keywords with their new values (and optional comments) to " "be altered." }, { "-a, --append =[/],...", "List of keywords with their new values (and optional comments) to " "be appended to the existing list of keywords." }, { "-d, --delete ,...", "List of keywords to be removed from the " "header." }, { "--force-alter-reserved-keywords", "Enable to alter reserved FITS keywords (use with caution)." }, { "-w, --rewrite", "Re-write the input file(s) directly. Use this option exclusively " "from -o|--output. " }, { NULL, NULL } }; int fprint_fiheader_long_help(FILE *fw,int is_wiki) { char *synopsis= "fiheader [opions] [input] [-o|--output ]"; char *description= "This program allows the user to read, set, alter or remove a set of values " "associated with the specified keywords from the primary header unit " "(a.k.a. simply \"header\") of a FITS image file."; fprint_generic_long_help(fw,is_wiki,fiheader_long_help,synopsis,description); return(0); } /*****************************************************************************/ static int format_v []= { FORMAT_VALUE,-1}; static int format_fv []= { FORMAT_FILE,FORMAT_VALUE,-1 }; static int format_kv []= { FORMAT_KEYWORD,FORMAT_VALUE,-1 }; static int format_fkv[]= { FORMAT_FILE,FORMAT_KEYWORD,FORMAT_VALUE,-1 }; int main(int argc,char *argv[]) { fits *img; FILE *fr,*fw; int is_help,ret; int i,j,is_rewrite,is_force,incnt,gkwcnt,mxflen; char *outname,**innames,**getkwlist,**setkwlist,*argformat; char *extension; int method; int *format; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; outname=NULL; innames=NULL; method=0; getkwlist=NULL; setkwlist=NULL; is_help=0,method=0; is_rewrite=is_force=0; argformat=NULL; extension=NULL; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-o|--output:%s",&outname, "-i|--input:%Dt",&innames, "-g|--get|-r|--read:%0f%Dt",&method,&getkwlist, "-s|--set|-u|--update:%1f%Dl%Dt",&method,&setkwlist,&setkwlist, "-a|--append:%1f%Dl%Dt",&method,&setkwlist,&setkwlist, "-d|--delete:%1f%Dl%Dt",&method,&setkwlist,&setkwlist, "-w|--rewrite:%f",&is_rewrite, "-F|--format:%s",&argformat, "-x|--extension:%s",&extension, "--force-alter-reserved-keywords:%f",&is_force, "-*:%e", "*:%Dl",&innames, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fiheader",FITSH_FIHEADER_VERSION,is_help); return(0); } else if ( 1mxflen ) mxflen=j; incnt++; } } if ( (method & 1) && getkwlist != NULL ) /* read some headers */ { gkwcnt=0; for ( i=0 ; getkwlist[i] != NULL ; i++ ) { for ( j=0 ; getkwlist[i][j] ; j++ ) { if ( getkwlist[i][j]==',' ) gkwcnt++; } gkwcnt++; } if ( format==NULL ) { if ( gkwcnt<=1 ) { if ( incnt<=1 ) format=format_v; else format=format_fv; } else { if ( incnt<=1 ) format=format_kv; else format=format_fkv; } } if ( incnt==0 ) { fr=stdin; ret=read_header_values_from_file(fr,extension,"-",getkwlist,stdout,format,1); } else { ret=0; for ( i=0 ; iheader,setkwlist,is_force); if ( outname==NULL ) fw=stdout; else fw=fopenwrite(outname); if ( fw==NULL ) { fprint_error("unable to create output file '%s'",outname); return(1); } fits_write(fw,img); fclosewrite(fw); } else { if ( incnt>1 && outname != NULL ) { fprint_error("invalid combination of command line arguments (output file name must be omitted)"); return(1); } if ( is_rewrite ) outname=NULL; for ( i=0 ; iheader,setkwlist,is_force); if ( outname != NULL ) fw=fopenwrite(outname); else fw=fopenwrite(innames[i]); if ( fw==NULL ) { fprint_error("unable to create output file"); return(1); } fits_write(fw,img); fclosewrite(fw); } } } return(0); } fitsh-0.9.2/src/ficombine.c0000644000175000017500000002411312771247712014154 0ustar apalapal/*****************************************************************************/ /* ficombine.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line user interface for combining more FITS images. */ /*****************************************************************************/ #define FITSH_FICOMBINE_VERSION "0.9" /*****************************************************************************/ #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "fitsmask.h" #include "statistics.h" #include "io/iof.h" #include "io/scanarg.h" #include "tensor.h" #include "common.h" #include "combine.h" #include "history.h" /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int fprint_ficombine_usage(FILE *fw) { fprintf(fw, "Usage:\tficombine [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t ... [-o|--output ]\n" "\t[-C|--comment] [-V|--verbose] [-M|--input-mask ]\n" "\t[-b|--bitpix ] [--max-memory ]\n" "\t[--data bitpix=,bscale=,bzero=|]\n"); fprintf(fw, "\t[-m|--mode average|median|rejection|sum|squaresum|scatter,or|and,\n" "\t ignorenegative,iterations=,[lower|upper|sigma]=,min,max]\n" "\t[-n|--ignore-negative] [--logical-or|--logical-and]\n"); return(0); } longhelp_entry ficombine_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-o, --output ", "The name of the output file (omitting or specifing '-' yields " "the output to be written to stdout)." }, { "--data ", "Output pixel data format specification." }, { "-b, --bitpix ", "Standard FITS output bitpix value." }, { "-M, --input-mask ", "Input mask file to co-add to output image." }, { "Generic combination specification:", NULL }, { "-m, --mode ", "Use the specified mode to combine images." }, { "-n, --ignore-negative", "Ignore (i.e. mask) pixels with negative values." }, { "--logical-or", "Use logical \"or\" combination between masks." }, { "--logical-and", "Use logical \"and\" combination between masks." }, { "Combination modes (a comma-separated list of these should follow -m|--mode):", NULL }, { "average, mean", "The mean value of the pixels." }, { "median", "The median value of the pixels." }, { "min, minimum", "The minimum value of the pixels." }, { "max, maximum", "The maximum value of the pixels." }, { "rejmed, rejection", "Median value after rejecting outliers." }, { "rejavg", "Mean value after rejecting outliers." }, { "iterations=", "Number of iterations to reject outliers." }, { "lower=, upper=, sigma=", "Outlier limit (lower, upper, both) in stddev." }, { "sum", "Sum of the pixel values." }, { "squaresum", "Sum for the squarers of the pixel values." }, { "scatter, stddev", "Pixel scatter (standard deviation)." }, { "or", "Use logical \"or\" combination between masks." }, { "and", "Use logical \"and\" combination between masks." }, { "ignorenegative", "Ignore (i.e. mask) pixels with negative values." }, { "ignorezero", "Ignore (i.e. mask) pixels with a zero value." }, { "ignorenegative", "Ignore (i.e. mask) pixels with positive values." }, { NULL,NULL } }; int fprint_ficombine_long_help(FILE *fw,int is_wiki) { char *synopsis= "ficombine [options] [-o|--output ]"; char *description= "The purpose of this program is to combine the input images (with the same " "sizes) to a single image. This combination refers to a kind of \"averaging\" " "for the images, however, other modes are also available."; fprint_generic_long_help(fw,is_wiki,ficombine_long_help,synopsis,description); return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { char **inputfiles,**inmasklist,*outname,*outmaskname, *fdpstring,*imagmodestr,*maxmemstr; char **mask,**outmask; int ninput,sx,sy; fits *outimg; FILE *fw; comimg *inputs; int i,j,is_help,apply_mask; compar cp_data,*cp=&cp_data; fitsdataparam fdp; size_t maxmem; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; is_help=is_verbose=is_comment=0; inmasklist=inputfiles=NULL; outmaskname=outname=NULL;imagmodestr=0; cp->mode=COM_MODE_AVG,cp->ignore_flag=0;apply_mask=0;cp->logicalmethod=0; fdp.bitpix=0;fdp.is_scale=0;fdp.bscale=1.0;fdp.bzero=0.0;fdpstring=NULL; maxmemstr=NULL; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help|--short-help|--help-short:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-o|--output:%s",&outname, "-b|--bitpix:%d",&fdp.bitpix, "--data:%s",&fdpstring, "--max-memory:%s",&maxmemstr, "-m|--mode:%s",&imagmodestr, "-M|--input-mask:%Dt",&inmasklist, "--output-mask:%s",&outmaskname, "-a|--apply-mask:%f",&apply_mask, "-n|--ignore-negative:%0f",&cp->ignore_flag, "--logical-or:%SN0f",&cp->logicalmethod, "--logical-and:%SN1f",&cp->logicalmethod, "--comment:%f",&is_comment,"(C):%f",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-*|+*:%e", "*:%l",&inputfiles, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"ficombine",FITSH_FICOMBINE_VERSION,is_help); return(0); } else if ( 1i.dim<2 || img->i.dim>3 ) { fprint_error("image dimension must be 2 or 3."); return(1); } else if ( img->i.dim==3 ) { fits_alloc_image_gen(img,img->i.dim,img->i.naxis); fits_read_image(fr,img); fclose(fr); fits_rescale(img); inputs[i].img=img; inputs[i].fr=NULL; } else { inputs[i].img=img; inputs[i].fr=fr; img->i.vdata=NULL; } } sx=inputs[0].img->i.sx, sy=inputs[0].img->i.sy; for ( i=1,j=0 ; ii.sx != sx || inputs[i].img->i.sy != sy ) j=1; } if ( j ) { fprint_error("size of input images differ"); return(1); } mask=fits_mask_create_empty(sx,sy); if ( inmasklist != NULL ) { if ( join_masks_from_files(mask,sx,sy,inmasklist) ) { fprint_error("unable to read one of the input mask files"); return(1); } } outmask=fits_mask_create_empty(sx,sy); outimg=fits_create(); fits_copy_full_header(outimg,inputs[0].img); fits_alloc_image(outimg,sx,sy); fits_reset_image(outimg); outimg->i.curr.bscale=1.0; outimg->i.curr.bzero=0.0; outimg->i.bit=-32; combine_images_from_files(inputs,ninput,outimg,cp,mask,outmask,NULL,0,maxmem); if ( fdp.bitpix ) outimg->i.bit=fdp.bitpix; if ( fdp.is_scale ) { outimg->i.read.bscale=fdp.bscale, outimg->i.read.bzero=fdp.bzero; } else if ( outimg->i.bit<0 ) { outimg->i.read.bscale=1.0, outimg->i.read.bzero=0.0; } fits_set_image_params(outimg); fits_backscale(outimg,outimg->i.read.bscale,outimg->i.read.bzero); mark_integerlimited_pixels(&outimg->i,outmask,outimg->i.bit,1,MASK_OVERSATURATED,MASK_OVERSATURATED); fits_mask_export_as_header(&outimg->header,1,outmask,sx,sy,NULL); if ( apply_mask ) { for ( i=0 ; ii.data[i][j]=0.0; } } } fits_history_export_command_line(outimg,"ficombine",FITSH_FICOMBINE_VERSION,argc,argv); if ( outname==NULL ) fw=stdout; else fw=fopenwrite(outname); if ( fw==NULL ) { fprint_error("unable to create output image"); return(1); } fits_write(fw,outimg); fclosewrite(fw); if ( outmaskname != NULL ) { fw=fopenwrite(outmaskname); if ( fw==NULL ) { fprint_error("unable to create output mask file"); return(1); } fits_write_header(fw,outimg); fclosewrite(fw); } fits_free(outimg); combine_cleanup(inputs,ninput); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/psf-determine.c0000644000175000017500000005654612771511015014770 0ustar apalapal/*****************************************************************************/ /* psf.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to PSF determination. The currently implemented */ /* algorithms are the following: */ /* - native (theoretically wrong, however, asymptotically works fine for */ /* wide stars, when FWHM is definitely larger than the pixel size); */ /* - integral (the method is somehow degenerated, the reason is not known; */ /* however, if an additional constraint (see: `kappa`) is applied, it */ /* seems to work, but the returned PSF is narrower than it should be); */ /* - circle (it works fine, but somehow it is also degenerated... still */ /* it is not known why, but the effect is negligable). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2004, 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #include "fitsh.h" #include "fitsmask.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/intersec/intersec-cri.h" #include "tensor.h" #include "psf.h" #include "psf-base.h" #include "psf-determine.h" /*****************************************************************************/ static double interpolate_subpixel(double **arr,int ix,int iy,double x0,double y0,double x1,double y1) { double ret; ret=arr[iy][ix]*(x1-x0)*(y1-y0); return(ret); } static double interpolate(double **arr,double x0,double y0,double x1,double y1) { double w,ret; int sig,ix0,ix1,iy0,iy1,x,y; sig=1; if ( x0>x1 ) sig=-sig,w=x0,x0=x1,x1=w; if ( y0>y1 ) sig=-sig,w=y0,y0=y1,y1=w; ix0=(int)floor(x0),iy0=(int)floor(y0); ix1=(int)floor(x1),iy1=(int)floor(y1); x0-=(double)ix0,y0-=(double)iy0; x1-=(double)ix1,y1-=(double)iy1; if ( ix0==ix1 ) { if ( iy0==iy1 ) ret=interpolate_subpixel(arr,ix0,iy0,x0,y0,x1,y1); else { ret=interpolate_subpixel(arr,ix0,iy0,x0,y0,x1,1.0); for ( y=iy0+1 ; y0.0 ) ret+=interpolate_subpixel(arr,ix0,iy1,x0,0.0,x1,y1); } } else { if ( iy0==iy1 ) { ret=interpolate_subpixel(arr,ix0,iy0,x0,y0,1.0,y1); for ( x=ix0+1 ; x0.0 ) ret+=interpolate_subpixel(arr,ix1,iy0,0.0,y0,x1,y1); } else { ret=interpolate_subpixel(arr,ix0,iy0,x0,y0,1.0,1.0); for ( x=ix0+1 ; x0.0 ) ret+=interpolate_subpixel(arr,ix1,iy0,0.0,y0,x1,1.0); for ( y=iy0+1 ; y0.0 ) ret+=interpolate_subpixel(arr,ix1,y,0.0,0.0,x1,1.0); } if ( y1>0.0 ) { ret+=interpolate_subpixel(arr,ix0,iy1,x0,0.0,1.0,y1); for ( x=ix0+1 ; x0.0 ) ret+=interpolate_subpixel(arr,ix1,iy1,0.0,0.0,x1,y1); } } } if ( sig>0 ) return(ret); else return(-ret); } int psf_determine_native(fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, int hsize,int grid,int order,psf *out,int use_biquad) { int i,j,k,l,n,nvar,sx,sy,t; int fsize,wwd; double ***psfstack,*pmonom,**amatrix,*bvector; double ox,oy,scale,igrid; double **bqc; psfcandidate *wc; ipoint *wi; double dx,dy,x1,y1,x2,y2,z,gbg,gamp,weight; int ix1,ix2,iy1,iy2; if ( img==NULL ) return(1); if ( img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( use_biquad ) { bqc=(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); biquad_coeff(img->data,sx,sy,bqc,NULL); } else bqc=NULL; fsize=2*hsize+1; wwd=fsize*grid; nvar=(order+1)*(order+2)/2; psfstack=(double ***)tensor_alloc_3d(double,wwd,wwd,nvar); pmonom=vector_alloc(nvar); bvector=vector_alloc(nvar); amatrix=matrix_alloc(nvar); ox=(double)sx*0.5, oy=(double)sy*0.5, scale=(double)sx; igrid=1.0/(double)grid; for ( i=0 ; inipoint <= 0 || wc->ipoints==NULL ) continue; x1=wc->cx+dx-((double)hsize+0.5),x2=x1+igrid; y1=wc->cy+dy-((double)hsize+0.5),y2=y1+igrid; ix1=(int)x1,iy1=(int)y1; ix2=(int)x2,iy2=(int)y2; if ( ix1<0 || ix2>=sx || iy1<0 || iy2>=sy ) continue; k=0; for ( l=0,wi=wc->ipoints ; lnipoint && k<4 ; l++,wi++ ) { if ( wi->x==ix1 && wi->y==iy1 ) k++; if ( wi->x==ix1 && wi->y==iy2 ) k++; if ( wi->x==ix2 && wi->y==iy1 ) k++; if ( wi->x==ix2 && wi->y==iy2 ) k++; } if ( k<4 ) continue; gbg =wc->bg; gamp=wc->amp; eval_2d_monoms(wc->cx,wc->cy,order,pmonom,ox,oy,scale); if ( bqc != NULL ) z=biquad_isc_int_rectangle(bqc,x1,y1,x2,y2)*(double)(grid*grid); else z=interpolate(img->data,x1,y1,x2,y2)*(double)(grid*grid); z=(z-gbg)/gamp; weight=gamp; for ( k=0 ; kcoeff=psfstack; out->hsize=hsize; out->grid=grid; out->order=order; out->ox=ox,out->oy=oy; out->scale=scale; return(0); } /*****************************************************************************/ typedef struct { int indx; double area; } idlist; int psf_determine_integral(fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, int hsize,int grid,int order,psf *out,double kappa) { int i,j,k,l,n,m,p,q,nvar,nfv,t,sx,sy,ttot; int fsize,wwd; double ***psfstack,*pmonom,**amatrix,*bvector; double ox,oy,scale,dgrid,poffs,kfactor,sumweight,flux,tflux,tamp; psfcandidate *wc; ipoint *wi; double x1,y1,x2,y2,wx,wy,z,gbg,gamp,weight,area,w,wk,wl; int ix1,ix2,iy1,iy2; idlist *ils; int nil; /*order=0;*/ /* okay, it is fixed for now. */ fprintf(stderr,"[1] clock = %12.3f\n",(double)clock()/(double)(CLOCKS_PER_SEC)); if ( img==NULL ) return(1); if ( img->data==NULL ) return(1); sx=img->sx,sy=img->sy; fsize=2*hsize+1; wwd=fsize*grid; nvar=(order+1)*(order+2)/2; psfstack=(double ***)tensor_alloc_3d(double,wwd,wwd,nvar); nfv=wwd*wwd*nvar; /* lot of variables to fit... */ pmonom =vector_alloc(nvar); bvector=vector_alloc(nfv); amatrix=matrix_alloc(nfv); ils=(idlist *)tensor_alloc_1d(idlist,wwd*wwd); ox=(double)sx*0.5, oy=(double)sy*0.5, scale=(double)sx; for ( i=0 ; iyvals==NULL ) { is_subtracted=0; break; } } if ( is_subtracted ) { for ( n=0 ; nnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; if ( mask != NULL && mask[wi->y][wi->x] ) continue; img->data[wi->y][wi->x] -= wc->yvals[m]; } } } dgrid=(double)grid; poffs=(double)hsize+0.5; ttot=0; sumweight=0.0; tflux=tamp=0.0; for ( n=0 ; nnipoint<=0 || wc->ipoints==NULL ) continue; gbg =wc->bg, /*gamp=wc->amp;*/ /* obsoleted */ flux=0.0; for ( m=0 ; mnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; flux+=img->data[wi->y][wi->x]-gbg; if ( is_subtracted ) { flux+=wc->yvals[m]; } } gamp=flux; if ( gamp<=0.0 ) continue; tflux+=flux; tamp +=wc->amp; weight=gamp; eval_2d_monoms(wc->cx,wc->cy,order,pmonom,ox,oy,scale); for ( m=0 ; mnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; z=img->data[wi->y][wi->x]; if ( is_subtracted ) { z+=wc->yvals[m]; } z=(z-gbg)/gamp; /*fprintf(stdout,"%d %d %g\n",wi->x,wi->y,z);*/ x1=dgrid*(((double)wi->x)-(wc->cx)+poffs),x2=x1+dgrid; y1=dgrid*(((double)wi->y)-(wc->cy)+poffs),y2=y1+dgrid; if ( x1<0.0 ) x1=0.0; if ( x1>wwd ) x1=wwd; if ( x2<0.0 ) x2=0.0; if ( x2>wwd ) x2=wwd; if ( y1<0.0 ) y1=0.0; if ( y1>wwd ) y1=wwd; if ( y2<0.0 ) y2=0.0; if ( y2>wwd ) y2=wwd; if ( x1==x2 || y1==y2 ) continue; ix1=(int)x1,iy1=(int)y1; ix2=(int)x2,iy2=(int)y2; nil=0;area=0.0; for ( i=iy1 ; i<=iy2 ; i++ ) { if ( iy1==iy2 ) wy=y2-y1; else if ( i==iy1 ) wy=1.0-(y1-(double)iy1); else if ( i==iy2 ) wy=(y2-(double)iy2); else wy=1.0; if ( wy<=0.0 ) continue; for ( j=ix1 ; j<=ix2 ; j++ ) { if ( ix1==ix2 ) wx=x2-x1; else if ( j==ix1 ) wx=1.0-(x1-(double)ix1); else if ( j==ix2 ) wx=(x2-(double)ix2); else wx=1.0; if ( wx<=0.0 ) continue; t=i*wwd+j; w=wx*wy; area+=w; ils[nil].indx=t; ils[nil].area=w; nil++; } } if ( nvar>1 ) { t=wwd*wwd; for ( i=0 ; i0.0 ) { int t0,t1,t2; for ( k=0 ; knipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; if ( mask != NULL && mask[wi->y][wi->x] ) continue; img->data[wi->y][wi->x] += wc->yvals[m]; } } } out->coeff=psfstack; out->hsize=hsize; out->grid=grid; out->order=order; out->ox=ox,out->oy=oy; out->scale=scale; fprintf(stderr,"[5] clock = %12.3f\n",(double)clock()/(double)(CLOCKS_PER_SEC)); return(0); } /*****************************************************************************/ typedef struct { double rmax; int order; double weight; int nvar,indx,icount; } ring; static int poly_to_fourier(int order,double *poly,double *four) { int o,k,f,s,b; if ( order<0 ) return(1); four[0]=poly[0]; poly++,four++; for ( o=1 ; o<=order ; o++ ) { four[0]=0.0; four[1]=0.0; for ( k=0,f=0,s=1,b=1 ; k<=o ; k++ ) { four[f]+=s*b*poly[k]; f=1-f; if ( f==0 ) s=-s; b=b*(o-k)/(k+1); } four+=2; poly+=o+1; } return(0); } int psf_determine_circle(fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, int hsize,int grid,int order,psf *out,double circwd,int circorder) { int c,i,j,k,l,n,m,p,q,nvar,nfv,t,sx,sy,circnvar,circpvar; int fsize,wwd,nil; double ***psfstack,*pmonom,**amatrix,*bvector,**crints, *crpoly,*crfour; double ox,oy,scale,dgrid,igrid,poffs,flux,tflux,tamp; psfcandidate *wc; ipoint *wi; double x1,y1,x2,y2,z,gbg,gamp,weight,area,wk,wl,wx,cwg,cr; idlist *ils; ring *rings,*rw; int nring,nrfvar,mxcorder; order=0; /* okay, it is fixed for now. */ /*circorder=0;*/ /* like this, which won't be trivial... */ if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; fsize=2*hsize+1; wwd=fsize*grid; nring=(int)(((double)hsize+0.5)/circwd);/* number of circle rings */ rings=(ring *)malloc(sizeof(ring)*nring); for ( i=0 ; imxcorder ) mxcorder=rings[i].order; } nvar=(order+1)*(order+2)/2; /* spatial variation of PSF */ nfv=nvar*nrfvar; /* total number of variables to fit */ circpvar=(mxcorder+1)*(mxcorder+2)/2; circnvar=1+2*mxcorder; pmonom =vector_alloc(nvar); bvector=vector_alloc(nfv); amatrix=matrix_alloc(nfv); crints =(double **)tensor_alloc_2d(double,nring,circnvar); crpoly =(double *)tensor_alloc_1d(double,circpvar); crfour =(double *)tensor_alloc_1d(double,circnvar); ils=(idlist *)tensor_alloc_1d(idlist,nrfvar); ox=(double)sx*0.5, oy=(double)sy*0.5, scale=(double)sx; tflux=tamp=0.0; if ( is_subtracted ) { for ( n=0 ; nnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; if ( mask != NULL && mask[wi->y][wi->x] ) continue; img->data[wi->y][wi->x] -= wc->yvals[m]; } } } for ( i=0 ; inipoint<=0 || wc->ipoints==NULL ) continue; gbg =wc->bg; /*gamp=wc->amp;*/ /* obsoleted */ flux=0.0; for ( m=0 ; mnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; flux+=img->data[wi->y][wi->x]-gbg; if ( is_subtracted ) { flux+=wc->yvals[m]; } } gamp=flux; if ( gamp<=0.0 ) continue; tflux+=flux; tamp +=wc->amp; weight=gamp; eval_2d_monoms(wc->cx,wc->cy,order,pmonom,ox,oy,scale); for ( m=0 ; mnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; z=img->data[wi->y][wi->x]; if ( is_subtracted ) { z+=wc->yvals[m]; } z=(z-gbg)/gamp; x1=(((double)wi->x)-(wc->cx)+poffs),x2=x1+1.0; y1=(((double)wi->y)-(wc->cy)+poffs),y2=y1+1.0; if ( x1<0.0 ) x1=0.0; if ( x1>fsize ) x1=fsize; if ( x2<0.0 ) x2=0.0; if ( x2>fsize ) x2=fsize; if ( y1<0.0 ) y1=0.0; if ( y1>fsize ) y1=fsize; if ( y2<0.0 ) y2=0.0; if ( y2>fsize ) y2=fsize; if ( x1==x2 || y1==y2 ) continue; x1-=poffs,x2-=poffs; y1-=poffs,y2-=poffs; for ( c=0 ; c=0 ; c-- ) { crints[p][c+1]-=crints[p][c]; } } nil=0;wx=0.0; for ( c=0 ; cnvar ; p++ ) { if ( crints[p][c] == 0.0 ) continue; ils[nil].indx=rw->indx+p; ils[nil].area=crints[p][c]; nil++; if ( rw->weight>wx ) wx=rw->weight; } } cwg=weight*wx; area=(x2-x1)*(y2-y1); if ( nvar>1 ) { for ( i=0 ; i=0 ; c-- ) { crints[p][c+1]-=crints[p][c]; } } area=0.0; for ( c=0 ; cnvar ; p++ ) { area+=crints[p][c]*bvector[k*nrfvar+rw->indx+p]; } } psfstack[k][i][j]=area*wx; } } } tensor_free(ils); tensor_free(crfour); tensor_free(crpoly); tensor_free(crints); matrix_free(amatrix); vector_free(bvector); vector_free(pmonom); free(rings); if ( is_subtracted ) { for ( n=0 ; nnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; if ( mask != NULL && mask[wi->y][wi->x] ) continue; img->data[wi->y][wi->x] += wc->yvals[m]; } } } out->coeff=psfstack; out->hsize=hsize; out->grid=grid; out->order=order; out->ox=ox,out->oy=oy; out->scale=scale; return(0); } /*****************************************************************************/ int psf_determine(fitsimage *img,char **mask, psfcandidate *cands,int ncand,int is_subtracted, psfdetermine *pd,psf *p) { int hsize,grid,order,ret; if ( pd==NULL ) return(-1); hsize=pd->hsize; grid =pd->grid; order=pd->order; if ( hsize<0 || grid<=0 || order<0 ) return(-1); switch ( pd->type ) { case PSF_DET_NATIVE: ret=psf_determine_native(img,mask,cands,ncand,is_subtracted, hsize,grid,order,p, pd->param.native.use_biquad); break; case PSF_DET_INTEGRAL: ret=psf_determine_integral(img,mask,cands,ncand,is_subtracted, hsize,grid,order,p, pd->param.integral.kappa); break; case PSF_DET_CIRCLE: ret=psf_determine_circle(img,mask,cands,ncand,is_subtracted, hsize,grid,order,p, pd->param.circle.width,pd->param.circle.order); break; default: ret=-1; } if ( ret ) return(ret); if ( pd->is_symmetrize ) psf_symmetrize(p); return(0); } /*****************************************************************************/ int drawback_psf(ipoint *ipoints,int nipoint,double *yvals, double x0,double y0,double amp,psf *p,double mul) { static double **bqc=NULL,**coeff=NULL,*cpoly=NULL; static int abx=0,aby=0,anvar=0; int i,j,k,nvar,bx,by; double x1,y1,x2,y2,px,py,afm,afo,sum; if ( ipoints==NULL || yvals==NULL ) return(-1); if ( p==NULL ) return(-1); nvar=(p->order+1)*(p->order+2)/2; bx=p->grid*(2*p->hsize+1); by=p->grid*(2*p->hsize+1); if ( bx>abx || by>aby ) { if ( bqc != NULL ) tensor_free(bqc); if ( coeff != NULL ) tensor_free(coeff); coeff=(double **)tensor_alloc_2d(double,bx,by); bqc =(double **)tensor_alloc_2d(double,2*bx+1,2*by+1); abx=bx,aby=by; } if ( nvar>anvar ) { if ( cpoly != NULL ) tensor_free(cpoly); cpoly=(double *)tensor_alloc_1d(double,nvar); anvar=nvar; } px=x0, py=y0; sum=0.0; for ( i=0 ; icoeff[k][i][j]; } coeff[i][j]=eval_2d_poly(px,py,p->order,cpoly,p->ox,p->oy,p->scale); sum+=coeff[i][j]; } } amp=mul*amp/sum; for ( i=0 ; igrid; afo=(double)p->grid*(0.5+(double)p->hsize); for ( i=0 ; i=bx ) x1=bx; if ( x2<0.0 ) x2=0.0; if ( x2>=bx ) x2=bx; if ( y1<0.0 ) y1=0.0; if ( y1>=by ) y1=by; if ( y2<0.0 ) y2=0.0; if ( y2>=by ) y2=by; if ( x1yvals==NULL ) is_subtracted=0; else if ( wc->nipoint>nyval ) nyval=wc->nipoint; } yvals=(double *)malloc(sizeof(double)*nyval); pvals=(double *)malloc(sizeof(double)*nyval); if ( is_subtracted ) { for ( n=0 ; nnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; if ( mask != NULL && mask[wi->y][wi->x] ) continue; img->data[wi->y][wi->x] -= wc->yvals[m]; } } } for ( n=0 ; nnipoint; if ( is_subtracted ) { for ( m=0 ; mipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; yvals[m] = img->data[wi->y][wi->x]+wc -> yvals[m]; } } else { for ( m=0 ; mipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; yvals[m] = img->data[wi->y][wi->x]; } } for ( m=0 ; mipoints,nipoint,pvals,wc->cx,wc->cy,+1.0,p,+1.0); maa=mab=mbb=0.0; va=vb=0.0; for ( m=0 ; mbg =b; wc->amp=a; } if ( is_subtracted ) { for ( n=0 ; nnipoint ; m++ ) { wi=&wc->ipoints[m]; if ( mask != NULL && mask[wi->y][wi->x] ) continue; if ( mask != NULL && mask[wi->y][wi->x] ) continue; img->data[wi->y][wi->x] += wc->yvals[m]; } } } free(pvals); free(yvals); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/Makefile.in0000644000175000017500000003050012771770673014126 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ CFLAGS=@CFLAGS@ -I$(INC) DEPTH=.. INC=$(DEPTH)/include CFLARGEFILE= DLEXT=@DLEXT@ DLSWC=@DLSWC@ DLDYN=@DLDYN@ DLLIB=@DLLIB@ TARGETS=fiarith ficalib ficombine ficonv fiheader fiign fiinfo fiphot \ firandom fistar fitrans \ grcollect grmatch grtrans \ lfit linear.$(DLEXT) \ fic_mpstack # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # DEP_FIARITH=\ history.o \ fitsmask.o \ statistics.o \ imgtrans.o \ common.o \ tensor.o \ ui.o \ longhelp.o MOD_FIARITH=\ io/iof.o \ io/scanarg.o \ psn/psn-general.o \ math/fit/lmfit.o \ math/poly.o \ math/spline/biquad.o \ math/dft/pbfft.o LIB_FIARITH=$(DEPTH)/libfits/libfits.a $(DEPTH)/libpsn/libpsn.a $(DEPTH)/librandom/librandom.a -lm DEP_FICOMBINE=\ fitsmask.o \ statistics.o \ tensor.o \ common.o \ ui.o \ longhelp.o \ history.o \ combine.o MOD_FICOMBINE=\ io/iof.o \ io/scanarg.o \ math/fit/lmfit.o \ math/poly.o LIB_FICOMBINE=$(DEPTH)/libfits/libfits.a -lm DEP_FICALIB=\ fitsmask.o \ statistics.o \ tensor.o \ common.o \ ui.o \ longhelp.o \ history.o \ str.o \ combine.o \ fbase.o MOD_FICALIB=\ io/iof.o \ io/scanarg.o \ io/tokenize.o \ math/fit/lmfit.o \ math/poly.o \ math/polyfit.o \ math/spline/spline.o \ math/splinefit.o LIB_FICALIB=$(DEPTH)/libfits/libfits.a -lm DEP_FICONV=\ history.o \ fitsmask.o \ statistics.o \ tensor.o \ common.o \ ui.o \ longhelp.o \ kernel.a MOD_FICONV=\ math/fit/lmfit.o \ math/poly.o \ math/spline/spline.o \ math/spline/bicubic.o \ math/spline/biquad.o \ io/iof.o \ io/tokenize.o \ io/scanarg.o LIB_FICONV=$(DEPTH)/libfits/libfits.a -lm DEP_FIHEADER=\ longhelp.o \ ui.o MOD_FIHEADER=\ io/iof.o \ io/scanarg.o \ io/tokenize.o LIB_FIHEADER=$(DEPTH)/libfits/libfits.a -lm DEP_FIIGN=\ fitsmask.o \ statistics.o \ longhelp.o \ ui.o \ maskdraw.o \ common.o \ history.o \ tensor.o MOD_FIIGN=\ math/fit/lmfit.o \ math/poly.o \ math/spline/biquad.o \ math/spline/biquad-isc.o \ io/iof.o \ io/scanarg.o \ io/tokenize.o LIB_FIIGN=$(DEPTH)/libfits/libfits.a -lm DEP_FIINFO=\ fitsmask.o \ statistics.o \ fiinfo-pnm.o \ fiinfo-image.o \ ui.o \ longhelp.o \ tensor.o MOD_FIINFO=\ math/fit/lmfit.o \ math/poly.o \ math/polyfit.o \ math/splinefit.o \ math/spline/biquad.o \ math/spline/bicubic.o \ math/spline/spline.o \ io/iof.o \ io/scanarg.o \ io/tokenize.o \ link/link.a LIB_FIINFO=$(DEPTH)/libfits/libfits.a -lm DEP_FIPHOT=\ fiphot-io.o \ fitsmask.o \ statistics.o \ magnitude.o \ common.o \ longhelp.o \ ui.o \ kernel.a \ apphot.o \ tensor.o \ weight-io.o \ weight-gen.o MOD_FIPHOT=\ math/intersec/intersec.o \ math/intersec/intersec-cri.o \ math/fit/lmfit.o \ math/poly.o \ math/spline/biquad.o \ math/spline/biquad-isc.o \ math/spline/spline.o \ math/polygon.o \ io/iof.o \ io/scanarg.o \ io/tokenize.o LIB_FIPHOT=$(DEPTH)/libfits/libfits.a -lm DEP_FIRANDOM=\ history.o \ longhelp.o \ ui.o \ tensor.o \ psf-io.o \ star-draw.o \ firandom-eval.o \ magnitude.o \ common.o \ fitsmask.o \ maskdraw.o \ weight-star.o \ weight-io.o MOD_FIRANDOM=\ math/fit/lmfit.o \ math/poly.o \ math/expint/expint.o \ math/spline/biquad.o \ math/spline/biquad-isc.o \ psn/psn-general.o \ math/intersec/intersec-cri.o \ io/iof.o \ io/scanarg.o \ io/tokenize.o LIB_FIRANDOM=$(DEPTH)/libfits/libfits.a $(DEPTH)/libpsn/libpsn.a $(DEPTH)/librandom/librandom.a -lm DEP_FISTAR=\ fistar-io.o \ fitsmask.o \ statistics.o \ tensor.o \ stars.a \ ui.o \ longhelp.o \ common.o \ imgtrans.o \ background.o \ magnitude.o \ psf.a MOD_FISTAR=\ math/fit/lmfit.o \ math/poly.o \ math/polyfit.o \ math/spline/biquad.o \ math/spline/biquad-isc.o \ math/expint/expint.o \ math/intersec/intersec-cri.o \ io/iof.o \ io/scanarg.o \ io/tokenize.o \ index/sort.o \ index/multiindex.o \ link/floodfill.o \ link/link.a \ math/delaunay.o LIB_FISTAR=$(DEPTH)/libfits/libfits.a -lm DEP_FITRANS=\ fitsmask.o \ fbase.o \ statistics.o \ transform.o \ common.o \ history.o \ ui.o \ longhelp.o \ tensor.o \ weight-io.o \ weight-gen.o MOD_FITRANS=\ io/iof.o \ io/scanarg.o \ io/tokenize.o \ io/format.o \ math/spline/biquad.o \ math/spline/biquad-isc.o \ math/spline/bicubic.o \ math/spline/spline.o \ math/fit/lmfit.o \ math/poly.o LIB_FITRANS=$(DEPTH)/libfits/libfits.a -lm DEP_GRCOLLECT=\ cache.o \ statistics.o \ longhelp.o \ ui.o \ str.o MOD_GRCOLLECT=\ io/iof.o \ io/scanarg.o \ io/tokenize.o LIB_GRCOLLECT=-lm DEP_GRMATCH=\ longhelp.o \ ui.o \ transform.o MOD_GRMATCH=\ io/iof.o \ io/scanarg.o \ io/tokenize.o \ math/fit/lmfit.o \ math/poly.o \ math/polyfit.o \ math/match.a LIB_GRMATCH=-lm DEP_GRTRANS=\ statistics.o \ tensor.o \ ui.o \ longhelp.o \ wcs.o \ transform.o MOD_GRTRANS=\ io/iof.o \ io/scanarg.o \ io/tokenize.o \ math/fit/lmfit.o \ math/poly.o \ math/polyfit.o LIB_GRTRANS=-lm DEP_LFIT=\ str.o \ xfunct.o \ longhelp.o \ ui.o \ lfit-builtin.o \ lfit-info.o MOD_LFIT=\ io/iof.o \ io/scanarg.o \ io/tokenize.o \ math/fit/lmfit.o \ math/dft/pbfft.o \ math/fit/downhill.o \ math/elliptic/elliptic.o \ math/elliptic/ntiq.o \ math/spline/spline.o LIB_LFIT=$(DEPTH)/libpsn/libpsn.a $(DEPTH)/libastro/libastro.a $(DEPTH)/librandom/librandom.a -lm $(DLLIB) # # # # # # # # # # # # # # # # # # # # DEP_FIC_MPSTACK=\ fitsmask.o \ fbase.o \ statistics.o \ transform.o \ common.o \ history.o \ ui.o \ longhelp.o \ tensor.o MOD_FIC_MPSTACK=\ io/iof.o \ io/scanarg.o \ io/tokenize.o \ io/format.o \ math/spline/bicubic.o \ math/spline/spline.o \ math/poly.o LIB_FIC_MPSTACK=$(DEPTH)/libfits/libfits.a -lm # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # DIRS=index io link math psn all: dirs $(MAKE) targets targets: $(TARGETS) dirs: $(DIRS) .PHONY: all clean dirs $(DIRS) targets ############################################################################### index: $(MAKE) -C index io: $(MAKE) -C io link: $(MAKE) -C link math: $(MAKE) -C math psn: $(MAKE) -C psn ############################################################################### background.o: background.c background.h $(CC) $(CFLAGS) -c background.c cache.o: cache.c cache.h $(CC) $(CFLAGS) -c cache.c combine.o: combine.c combine.h $(CC) $(CFLAGS) -c combine.c fbase.o: fbase.c fbase.h $(CC) $(CFLAGS) -c fbase.c imgtrans.o: imgtrans.c imgtrans.h $(CC) $(CFLAGS) -c imgtrans.c magnitude.o: magnitude.c magnitude.h $(CC) $(CFLAGS) -c magnitude.c pselect.o: pselect.c pselect.h $(CC) $(CFLAGS) -c pselect.c statistics.o: statistics.c statistics.h $(CC) $(CFLAGS) -c statistics.c str.o: str.c str.h $(CC) $(CFLAGS) -c str.c tensor.o: tensor.c tensor.h $(CC) $(CFLAGS) -c tensor.c transform.o: transform.c transform.h $(CC) $(CFLAGS) -c transform.c # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # fitsmask.o: fitsmask.c fitsmask.h $(CC) $(CFLAGS) -c fitsmask.c apphot.o: apphot.c apphot.h fitsh.h $(CC) $(CFLAGS) -c apphot.c common.o: common.c common.h fitsh.h $(CC) $(CFLAGS) -c common.c psf-base.o: psf-base.c psf-base.h psf.h $(CC) $(CFLAGS) -c psf-base.c psf-io.o: psf-io.c psf-io.h psf.h $(CC) $(CFLAGS) -c psf-io.c psf-determine.o: psf-determine.c psf-determine.h psf.h stars.h $(CC) $(CFLAGS) -c psf-determine.c ui.o: ui.c fitsh.h $(CC) $(CFLAGS) -c ui.c history.o: history.c fitsh.h $(CC) $(CFLAGS) -c history.c maskdraw.o: maskdraw.c maskdraw.h $(CC) $(CFLAGS) -c maskdraw.c kernel-base.o: kernel-base.c kernel.h fitsh.h $(CC) $(CFLAGS) -c kernel-base.c kernel-io.o: kernel-io.c kernel.h fitsh.h $(CC) $(CFLAGS) -c kernel-io.c kernel.a: kernel-base.o kernel-io.o $(AR) src kernel.a kernel-base.o kernel-io.o $(RANLIB) kernel.a star-base.o: star-base.c stars.h $(CC) $(CFLAGS) -c star-base.c star-draw.o: star-draw.c stars.h $(CC) $(CFLAGS) -c star-draw.c star-model.o: star-model.c star-model.h stars.h $(CC) $(CFLAGS) -c star-model.c star-psf.o: star-psf.c stars.h $(CC) $(CFLAGS) -c star-psf.c star-cand-pp.o: star-cand-pp.c stars.h $(CC) $(CFLAGS) -c star-cand-pp.c star-cand-biq.o: star-cand-biq.c stars.h $(CC) $(CFLAGS) -c star-cand-biq.c star-cand-trb.o: star-cand-trb.c stars.h $(CC) $(CFLAGS) -c star-cand-trb.c star-cand-lnk.o: star-cand-lnk.c stars.h $(CC) $(CFLAGS) -c star-cand-lnk.c MOD_STARS=star-base.o star-model.o star-psf.o star-draw.o \ star-cand-pp.o star-cand-biq.o star-cand-trb.o star-cand-lnk.o MOD_PSF=psf-io.o psf-base.o psf-determine.o stars.a: $(MOD_STARS) $(AR) src stars.a $(MOD_STARS) $(RANLIB) stars.a psf.a: $(MOD_PSF) $(AR) src psf.a $(MOD_PSF) $(RANLIB) psf.a wcs.o: wcs.c wcs.h $(CC) $(CFLAGS) -c wcs.c weight-gen.o: weight-gen.c weight.h $(CC) $(CFLAGS) -c weight-gen.c weight-io.o: weight-io.c weight.h $(CC) $(CFLAGS) -c weight-io.c weight-star.o: weight-star.c weight.h $(CC) $(CFLAGS) -c weight-star.c longhelp.o: longhelp.c longhelp.h $(CC) $(CFLAGS) -c longhelp.c ############################################################################### fiarith: fiarith.c fitsh.h $(DEP_FIARITH) $(MOD_FIARITH) $(CC) $(CFLAGS) -o fiarith fiarith.c $(DEP_FIARITH) $(MOD_FIARITH) $(LIB_FIARITH) ficalib: ficalib.c fitsh.h $(DEP_FICALIB) $(MOD_FICALIB) $(CC) $(CFLAGS) -o ficalib ficalib.c $(DEP_FICALIB) $(MOD_FICALIB) $(LIB_FICALIB) ficombine: ficombine.c fitsh.h $(DEP_FICOMBINE) $(MOD_FICOMBINE) $(CC) $(CFLAGS) -o ficombine ficombine.c $(DEP_FICOMBINE) $(MOD_FICOMBINE) $(LIB_FICOMBINE) ficonv: ficonv.c fitsh.h $(DEP_FICONV) $(MOD_FICONV) $(CC) $(CFLAGS) -o ficonv ficonv.c $(DEP_FICONV) $(MOD_FICONV) $(LIB_FICONV) fiheader: fiheader.c fitsh.h $(DEP_FIHEADER) $(MOD_FIHEADER) $(CC) $(CFLAGS) -o fiheader fiheader.c $(DEP_FIHEADER) $(MOD_FIHEADER) $(LIB_FIHEADER) fiign: fiign.c fitsh.h $(DEP_FIIGN) $(MOD_FIIGN) $(CC) $(CFLAGS) -o fiign fiign.c $(DEP_FIIGN) $(MOD_FIIGN) $(LIB_FIIGN) fiinfo-image.o: fiinfo-image.c fiinfo.h $(CC) $(CFLAGS) -c fiinfo-image.c fiinfo-pnm.o: fiinfo-pnm.c fiinfo.h $(CC) $(CFLAGS) -c fiinfo-pnm.c fiinfo: fiinfo.c fiinfo.h fitsh.h $(DEP_FIINFO) $(MOD_FIINFO) $(CC) $(CFLAGS) -o fiinfo fiinfo.c $(DEP_FIINFO) $(MOD_FIINFO) $(LIB_FIINFO) firandom-eval.o: firandom-eval.c firandom.h $(CC) $(CFLAGS) -c firandom-eval.c firandom: firandom.c fitsh.h $(DEP_FIRANDOM) $(MOD_FIRANDOM) $(CC) $(CFLAGS) -o firandom firandom.c $(DEP_FIRANDOM) $(MOD_FIRANDOM) $(LIB_FIRANDOM) fiphot-io.o: fiphot-io.c fiphot.h $(CC) $(CFLAGS) -c fiphot-io.c fiphot: fiphot.c fitsh.h $(DEP_FIPHOT) $(MOD_FIPHOT) $(CC) $(CFLAGS) -o fiphot fiphot.c $(DEP_FIPHOT) $(MOD_FIPHOT) $(LIB_FIPHOT) fistar-io.o: fistar-io.c fistar.h $(CC) $(CFLAGS) -c fistar-io.c fistar: fistar.c fitsh.h $(DEP_FISTAR) $(MOD_FISTAR) fistar.h $(CC) $(CFLAGS) -o fistar fistar.c $(DEP_FISTAR) $(MOD_FISTAR) $(LIB_FISTAR) fitrans: fitrans.c fitsh.h $(DEP_FITRANS) $(MOD_FITRANS) $(CC) $(CFLAGS) -o fitrans fitrans.c $(DEP_FITRANS) $(MOD_FITRANS) $(LIB_FITRANS) grcollect: grcollect.c fitsh.h $(DEP_GRCOLLECT) $(MOD_GRCOLLECT) $(CC) $(CFLAGS) -o grcollect grcollect.c $(DEP_GRCOLLECT) $(MOD_GRCOLLECT) $(LIB_GRCOLLECT) grmatch: grmatch.c fitsh.h $(DEP_GRMATCH) $(MOD_GRMATCH) $(CC) $(CFLAGS) -o grmatch grmatch.c $(DEP_GRMATCH) $(MOD_GRMATCH) $(LIB_GRMATCH) grtrans: grtrans.c fitsh.h $(DEP_GRTRANS) $(MOD_GRTRANS) $(CC) $(CFLAGS) -o grtrans grtrans.c $(DEP_GRTRANS) $(MOD_GRTRANS) $(LIB_GRTRANS) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # xfunct.o: xfunct.c xfunct.h $(CC) $(CFLAGS) -c xfunct.c lfit-builtin.o: lfit-builtin.c lfit-builtin.h $(CC) $(CFLAGS) -c lfit-builtin.c lfit-info.o: lfit-info.c lfit-info.h $(CC) $(CFLAGS) -c lfit-info.c lfit: lfit.c $(DEP_LFIT) $(MOD_LFIT) $(CC) $(CFLAGS) -o lfit lfit.c $(DEP_LFIT) $(MOD_LFIT) $(DLDYN) $(LIB_LFIT) linear.o: linear.c $(CC) $(CFLAGS) -c linear.c linear.$(DLEXT): linear.o $(LD) -o linear.$(DLEXT) linear.o $(DLSWC) -lc chmod 644 linear.$(DLEXT) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # fic_mpstack: fic_mpstack.c fitsh.h $(DEP_FIC_MPSTACK) $(CC) $(CFLAGS) -o fic_mpstack fic_mpstack.c $(DEP_FIC_MPSTACK) $(MOD_FIC_MPSTACK) $(LIB_FIC_MPSTACK) ############################################################################### clean: $(MAKE) -C index clean $(MAKE) -C io clean $(MAKE) -C link clean $(MAKE) -C math clean $(MAKE) -C psn clean rm -f *.o *.a $(TARGETS) fitsh-0.9.2/src/grtrans.c0000644000175000017500000012017012771247716013705 0ustar apalapal/* grtrans.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line utility to fit general two-dimensional transformations. */ /*****************************************************************************/ #define FITSH_GRTRANS_VERSION "1.0" /*****************************************************************************/ #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/polyfit.h" #include "wcs.h" #include "transform.h" #include "common.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ typedef struct { int refx,refy; int nval; int *fitc; int *outc; int is,id,ik, os,od,ok; int weight,wgh_is_mag; double wgh_power; } colinfo; typedef struct { double x,y; double weight,delta; double *vals; } fpoint; /*****************************************************************************/ int fit_wcs(fpoint *fps,int nfp,wcsinit *wi,wcsdata *wcs) { int i,k,nvar,order; point *ps; double *vfits[4],cdelt1,cdelt2,idelt,lxx,lxy,lyx,lyy; double ra,de,x,y,z; if ( wi==NULL || wcs==NULL ) return(-1); memmove(&wcs->init,wi,sizeof(wcsinit)); order=wcs->init.order; if ( order<=0 ) return(-1); nvar=(order+1)*(order+2)/2; for ( k=0 ; k<4 ; k++ ) { vfits[k]=(double *)malloc(sizeof(double)*nvar); } ps=(point *)malloc(sizeof(point)*nfp); for ( i=0 ; iinit.ra0,wcs->init.de0,&x,&y,&z); wcs_project_distort(wcs->init.type,&x,&y,&z); fps[i].x=x*M_R2D; fps[i].y=y*M_R2D; } for ( i=0 ; i0.0 ) /* Det > 0 */ { if ( lxx+lyy>=0.0 ) /* Tr >= 0 */ { cdelt1=+1.0/idelt; cdelt2=+1.0/idelt; } else { cdelt1=-1.0/idelt; cdelt2=-1.0/idelt; } } else { if ( lxx>0.0 ) { cdelt1=+1.0/idelt; cdelt2=-1.0/idelt; } else { cdelt1=-1.0/idelt; cdelt2=+1.0/idelt; } } for ( i=0 ; icrpix1=vfits[2][0]; wcs->crpix2=vfits[3][0]; wcs->cdelt1=cdelt1; wcs->cdelt2=cdelt2; wcs->pixpoly[0]=vfits[0]; wcs->pixpoly[1]=vfits[1]; wcs->prjpoly[0]=vfits[2]; wcs->prjpoly[1]=vfits[3]; return(0); } int dump_wcs_coeff_headers(FILE *fw,char *type,int order,double *coeff) { int i,j,k; fprintf(fw,"%s_ORDER=%d,\n",type,order); for ( i=1,k=1 ; i<=order ; i++ ) { for ( j=0 ; j<=i ; j++,k++ ) { fprintf(fw,"%s_%d_%d=%.12g,\n",type,i-j,j,coeff[k]); } } return(0); } int dump_wcs_headers(FILE *fw,wcsdata *wcs) { char *ttype; fprintf(fw,"WCSAXES=%d,\n",2); switch ( wcs->init.type ) { case WCS_SIN: ttype="SIN"; break; case WCS_TAN: ttype="TAN"; break; case WCS_ARC: ttype="ARC"; break; default: ttype="???"; break; } fprintf(fw,"CTYPE1='RA---%s-SIP',\n",ttype); fprintf(fw,"CTYPE2='DEC--%s-SIP',\n",ttype); fprintf(fw,"CRVAL1=%.4f,\n",wcs->init.ra0); fprintf(fw,"CRVAL2=%.4f,\n",wcs->init.de0); fprintf(fw,"CDELT1=%.12g,\n",wcs->cdelt1); fprintf(fw,"CDELT2=%.12g,\n",wcs->cdelt2); fprintf(fw,"CRPIX1=%.3f,\n",wcs->crpix1+1.0); fprintf(fw,"CRPIX2=%.3f,\n",wcs->crpix2+1.0); dump_wcs_coeff_headers(fw,"A" ,wcs->init.order,wcs->pixpoly[0]); dump_wcs_coeff_headers(fw,"B" ,wcs->init.order,wcs->pixpoly[1]); dump_wcs_coeff_headers(fw,"AP",wcs->init.order,wcs->prjpoly[0]); dump_wcs_coeff_headers(fw,"BP",wcs->init.order,wcs->prjpoly[1]); fprintf(fw,"CROTA2=0.0\n"); return(0); } int free_wcs(wcsdata *wcs) { if ( wcs->pixpoly[0] != NULL ) free(wcs->pixpoly[0]); if ( wcs->pixpoly[1] != NULL ) free(wcs->pixpoly[1]); if ( wcs->prjpoly[0] != NULL ) free(wcs->prjpoly[0]); if ( wcs->prjpoly[1] != NULL ) free(wcs->prjpoly[1]); return(0); } /*****************************************************************************/ static char *wrninappr="Warning: inappropriate content in line %d, skipped.\n"; int read_data_points(FILE *fr,colinfo *col,fpoint **rfps,int *rnfp) { char *rbuff,**cmd; fpoint *fps; int nfp,n,k,i,j,ln; double xr,yr,wr,w,*vals; fps=NULL; nfp=0; ln=0; while ( ! feof(fr) ) { rbuff=freadline(fr); if ( rbuff==NULL ) break; ln++; remove_newlines_and_comments(rbuff); cmd=tokenize_spaces_dyn(rbuff); if ( cmd==NULL ) { free(rbuff);continue; } for ( n=0 ; cmd[n] != NULL ; ) n++; if ( n==0 ) { free(rbuff);free(cmd);continue; } k=0; if ( col->refxrefx],"%lg",&xr); if ( col->refyrefy],"%lg",&yr); if ( k<2 || ! ( isfinite(xr) && isfinite(yr) ) ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); free(rbuff);free(cmd);continue; } if ( 0<=col->weight && col->weightweight],"%lg",&wr); if ( k<1 || ! isfinite(wr) ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); free(rbuff);free(cmd);continue; } if ( col->wgh_is_mag ) { wr=exp(-0.4*M_LN10*(wr-20.0)); } else if ( wr<0.0 ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); free(rbuff);free(cmd);continue; } if ( col->wgh_power != 1.0 && wr>0.0 ) { wr=pow(wr,col->wgh_power); } } else wr=1.0; if ( nfp==0 ) fps=(fpoint *)malloc(sizeof(fpoint)); else fps=(fpoint *)realloc(fps,sizeof(fpoint)*(nfp+1)); vals=(double *)malloc(sizeof(double)*col->nval); k=0; for ( i=0 ; inval ; i++ ) { if ( col->fitc[i]fitc[i]],"%lg",&w); if ( j && ! isfinite(w) ) j=0; k+=j; vals[i]=w; } } if ( knval ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); free(vals); free(rbuff);free(cmd);continue; } fps[nfp].x=xr; fps[nfp].y=yr; fps[nfp].weight=wr; fps[nfp].vals=vals; nfp++; }; *rfps=fps; *rnfp=nfp; return(0); } /*****************************************************************************/ int parse_number_list(char *p,int *rn,int **rfitc) { int w,n,*fitc; fitc=NULL;n=0; while ( *p ) { while ( isspace((int)*p) ) p++; if ( sscanf(p,"%d",&w)<1 ) { if ( fitc != NULL ) free(fitc); return(1); } fitc=(int *)realloc(fitc,sizeof(int)*(n+1)); fitc[n]=w; n++; while ( isdigit((int)*p) || *p=='-' ) p++; while ( isspace((int)*p) || *p==',' ) p++; } *rn=n; *rfitc=fitc; return(0); } /*****************************************************************************/ int fprint_grtrans_usage(FILE *fw) { fprintf(fw, "Usage:\tgrtrans [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[-C|--comment] [-V|--verbose]\n" "\t[|-i |--input ] [-o|--output ]\n"); fprintf(fw, "Fit parameters:\n" "\t[-a|--order order] [-f|--offset ,] [--scale ]\n" "\t[-n|--iterations ] [-r|--rejection-level ]\n" "\t[--output-transformation|-ot ]\n" "\t[--weight|-w [magnitude],[power=]\n"); fprintf(fw, "Transformation parameters:\n" "\t[--reverse] [-T|--input-transformation ]\n"); fprintf(fw, "Input/output format parameters:\n" "\t[--col-ref|--col-xy <>,<>] [--col-fit <>,...] [--col-out <>,...]\n" "\t[--col-weight <>] [--col-sdk <>,<>,<> [--col-out-sdk <>,<>,<>]]\n" "\t[--preserve-comments]\n"); fprintf(fw, "WCS conversion and fitting parameters:\n" "\t[--wcs [sin|arc|tan],order=,ra=,dec=,\n" "\t [degrees|radians|scale=]] [--col-radec|--col-pixel <>,<>]\n"); fprintf(fw, "Note that 'WCS fitting' and 'WCS conversion' are three different things.\n" "Because of 'fitting WCS' is a derivation of some FITS headers required by the\n" "standard (see e.g. Calabretta & Greisen, A&A, 395, 1077), this invocation fits\n" "the distortion coefficients and dumps the appropriate keyword=value pairs.\n"); fprintf(fw, "'WCS conversion' is something different: with this, one can project RA/DEC\n" "values (using a projection method: orthographic, arc or gnomonic) and scale\n" "into plane and vice versa. The confusion is due to the fact that both things\n" "require almost the same external parameters, given after the switch '--wcs'.\n"); return(0); } longhelp_entry grtrans_long_help[]= { LONGHELP_OPTIONS, { "General administrative options:", NULL }, { "-h, --help", "Give general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Give some version information about the program." }, { "-C, --comment", "Comment the output." }, { "Options for input/output specification:", NULL }, { ", -i , --input ", "Name of the input file. If this switch is omitted, the input " "is read from stdin (specifying some input is mandatory)." }, { "-o , --output , --output-matched ", "Name of the output file, if the program was used for transforming " "coordinate lists." }, { "-T, --input-transformation ", "Name of the input transformation file (see also the " "notes below)." }, { "--output-transformation ", "Name of the output file containing the fitted geometrical " "transformation, in human-readable format (see also the notes below)." }, { "In all of the above input/output file specifications, the replacement " "of the file name by \"-\" (a single minus sign) forces the " "reading from stdin or writing to stdout. Note that all parts " "of the any line after \"#\" (hashmark) are treated as a comment, " "therefore ignored.", NULL }, { __extension__ "Note that there is no explicit switch for distinguishing between the " "fitting and the evaluating purposes of the program. If " "--input-transformation has been specified, the program implies " "that the user wants to evaluate a function described by this " "existing transformation file. On the other hand, if " "--output-transformation has been specified, the program fits " "the parameters of the function and stores the resulted " "transformation file as it specified by the argument of " "this option. In other words, if no WCS or spherical " "(de)projection declared by the directives of --wcs, one of " "these two switches should be given in the " "command line.", NULL }, { "", NULL }, { "General options for fitting polynomial coefficients:", NULL }, { "--col-xy ,", "Column indices for the independent values. In the current " "implementation, grtrans can only fit polynomial functions of " "exactly 2 independent variables. Lines where these columns do " "not contain valid real numbers are excluded." }, { "--col-fit <>[,<>[,<>]...]", "Column indices for the dependent values. In the current " "implementation, grtrans can only fit 2 dimensional polynomial " "functions to arbitrary dimensional data. The dimension of the " "fitted data is specified indirectly, by the number of column " "indices specified after this switch." }, { "-a , --order ", "Order of the fitted polynomial function. It can be any " "positive integer." }, { "-n , --iterations ; -r , --rejection-level ", "These switches specify the total number of rejection iterations " "of outlyer points and the rejection level in sigma units. " "By default, no rejection is applied, therefore all valid " "lines are used. " }, { "--col-weight ", "Column index for optional weights. If specified, this column " "should contain a valid non-negative real number which is used as a " "weight during the least-squares fit. " }, { "--weight [magnitude],[power=

]", __extension__ "These directives specify the weights which are used during " "the fit of the functions or transformations. For example, " "in practice it is useful in the following situation. We try " "to match star lists, then the fainter stars are believed to " "have higher astrometrical errors, therefore they should have " "smaller influence in the fit. We can take the weights " "from a given colum, specified by the index after --col-weight " "(see above). The weights can be derived from stellar " "magnitudes, if so, specify \"magnitude\" to convert the read " "values in magnitude to flux. The real weights then is " "the \"power\"th power of the flux. The default value of " "the \"power\" is 1, however, for the maximum-likelihood " "estimation of an assumed Gaussian distribution, the weights " "should be the second power of the fluxes." }, { "-ot, --output-transformation ", "Name of the output transformation file containing the result of " "the fit (see above)." }, { "General options for transformation or function evaluation:", NULL }, { "--input-transformation ", "Name of the input transformation file containing the desired " "transformation (see above)." }, { "--reverse, --inverse", "Perform inverse transformation. This is a valid option only if " "the dimension of the fitted function is the same as the dimension " "of the independent variables (namely, 2, because in the actual " "implementation the latter can only be 2)." }, { "--col-xy ,", "Column indices for the independent values. In the current " "implementation, `grtrans` can only fit polynomial functions of " "exactly 2 independent variables. Lines where these columns " "do not contain valid real numbers are excluded." }, { "--col-out <>[,<>[,<>]...]", "Column indices for the evaluated output variables. The number of " "indices listed here should be the same as the number of " "independent functions stored in the input transformation file." }, { "General options for transformation composition:", NULL }, { "--input-transformation ", "Name of the input transformation file." }, { "--scale ", "Scale factor." }, { "--offset ,", "Shift. The affine transformation with which the input " "transformation is composed is going to be: x'=dx+s*x, y'=dy+s*y." }, { "--output-transformation ", "Name of the output transformation file containing the " "result of the composition." }, { "Options for spherical projection and deprojection:", NULL }, { "--wcs [sin|arc|tan],ra=,dec=,[degrees|radians|scale=", __extension__ "This set of directives specify the common parameters of " "the spherical projection or deprojection. The \"sin\", \"arc\" " "and \"tan\" directives set the type of projection to orthographic, " "arc and gnomonic, respectively. The values after \"ra\" and " "\"dec\" ( and ) specify the center of the projection " "(right ascension and declination, respectively, in degrees). " "The \"degrees\", \"radians\" or the \"scale=\" directives " "specify the scaling of the output. The directive \"degrees\" " "is equivalent to set \"scale=57.29577951308232087721\" " "(180 over \\Pi), this is the default. The directive " "\"radians\" is equivalent to set \"scale=1\"." }, { "--col-radec ,", "Column indices for RA and DEC values. This option implies " "projection." }, { "--col-pixel ,", "Column indices for X and Y projected values. This option " "implies deprojection." }, { "--col-out <>,<>", "Column indices for the output values (which are X and Y for " "projection and RA, DEC for deprojection)." }, { "Options for fitting WCS information:", NULL }, { "--wcs [sin|arc|tan],ra=,dec=,order=", __extension__ "This set of directives specify the common parameters of WCS " "fitting. The projection can be orthographic, arc or gnomonic " "(however, there are dosens of projections implemented in the " "FITS WCS system, but for practical purposes, such projections " "seem to be more than enough). The center of the fit is set " "by \"ra\" and \"dec\" (RA and DEC, in degrees). The distortion " "order is specified by order. Note that the RA and DEC values " "specified here can only be an assumed values. " }, { "--col-ref <>,<>", "Column indices for the Ra and Dec values." }, { "--col-fit <>,<>", "Column indices for the pixel values." }, { "Note that in this case, the set of the appropriate FITS keyword=value " "pairs are written directly stdout, not in the file specified by " "the options --output or --output-transformation." }, { "", NULL }, LONGHELP_EXAMPLES, { __extension__ "Here is an example for a complete astrometry problem which demonstrates " "the proper usage of the programs grmatch and grtrans. Let us assume " "that we have 1/ a reference star catalogue, named \"catalog.dat\", a " "file with four columns: the first is the identifier of the star, the " "second and third are the celestial coordinates (RA and DEC, in degrees), " "and the last is the magnitude of the stars; 2/ an astronomical image, " "named \"img.fits\" (not crucial for the astrometry itself, it is " "required only by the demonstration of the export of FITS WCS headers); " "and 3/ a list of decected stars (from \"img.fits\"), named \"img.star\", " "a file with three columns: the first two are the pixel coordinates and " "the third is an estimation of the flux (in ADUs, not in " "magnitudes).", NULL }, { "", NULL }, { __extension__ "Let us also denote the celestial coordinates of the center of the " "image by R and D, the RA and DEC values, in degrees and, " "for example let R=220 and D=25, a field in the Bootes. " "Let us also assume that the size of our field (both the " "catalog and the list of the deceted stars) is 3 degrees and " "there are approximately 4000-4000 stars both in the reference " "catalog and in the list of the detected stars. Because we have " "such a large amount of stars, one can use only a fraction of " "them for triangulation. " }, { "", NULL } , { __extension__ "The first step is to make a projection from the sky, " "centered around the center of our image:", NULL }, { "", NULL }, { "", "grtrans --input catalog.dat --wcs tan,degrees,ra=220,dec=25 " "--col-radec 2,3 --col-out 5,6 --output img.proj" }, { "The second step is the point matching:", NULL}, {"", NULL }, { "", "grmatch --reference img.proj --col-ref 5,6 --col-ref-ordering -4 " "--input img.star --col-inp 1,2 --col-inp-ordering +3 " "--match-points --order 4 " "--triangulation auto,unitarity=0.01,maxnumber=1000,conformable " "--max-distance 1 --weight reference,column=4,magnitude,power=2 " "--comment --output-transformation img.trans" }, { __extension__ "This grmach invocation matches the stars from projected reference " "catalog, \"img.proj \" and the detected stars. The \"--order 4\" " "specifies a fourth-order polynomial fit, which is, in practice, " "good for a field with the size of 3 degrees. The directives " "after \"--weight\" makes the magnitudes taken from the reference file " "to be used as a weight for fitting. This invocation yields " "one new file, \"img.trans\" which stores the fitted 4th-order " "polynomial transformation which transforms the projected " "coordinates to the system of the image." , NULL }, { "", NULL }, { "The next step is the astrometrical transformation, we create a " "\"local\" catalog, which is the original catalog extended with " "the proper X and Y plate coordinates:", NULL }, { "", NULL }, { "", "grtrans --input img.proj --col-xy 5,6 " "--input-transformation img.trans --col-out 7,8 --output img.cat" }, { "This invocation yields an other new file, \"img.cat\" which has 8 " "columns. The first six columns are the same as it was in \"img.proj\" " "(identifier, RA, DEC, magnitude and projected X, Y coordinates), " "the last two colums are the fitted plate coordinates. Then, the " "proper WCS headers can be determined by the " "following call:", NULL }, { "", NULL }, { "", "grtrans --input img.cat --col-ref 2,3 --col-fit 7,8 " "--wcs tan,order=4,ra=220,dec=25 >img.wcs" }, { "The newly created file, img.wcs contains the FITS " "\"keyword\"=\"value\" pairs, which can be exported to \"img.fits\" " "to have a standard header extended by the WCS information. " "For exporting, the program fiheader(1) can be used:" }, { "", NULL }, { "", "fiheader img.fits --rewrite --update \"$(cat img.wcs)\"" }, { "Note that the last two grtrans calls can be replaced by a single " "pipeline, when the file img.cat is not created:", NULL}, { "", NULL }, { "", "grtrans --input img.proj --col-xy 5,6 --input-transformation " "img.trans --col-out 7,8 --output - | grtrans --input - " "--col-ref 2,3 --col-fit 7,8 " "--wcs tan,order=4,ra=220,dec=25 >img.wcs" }, { NULL, NULL }, }; int fprint_grtrans_long_help(FILE *fw,int is_wiki) { char *synopsis= "grtransh [options] [-o ]"; char *description= __extension__ "The main purpose of the program `grtrans` is to transform coordinate " "lists and fit transfomrations to input data. The transformation can be " "one of the following methods. 1. Evaluate polynomial functions (with " "arbitrary order)of two independent values. 2. Two dimensional spherical " "projection (converting to RA/DEC or longitude/latitude values to projected " "coordinates on a given tangent plane. 3. Two dimensional spherical " "de-projection (converting tangent planar coordinates to RA/DEC or " "longitude/latitude values). 4. Compose arbitrary polynomial functions of " "two independent values with arbitrary two-dimensional affine (or linear) " "transformations. " "The program also can be used to fit functions, namely fit the " "coefficients of arbitrary-order polynomial functions of two independent " "values or fit WCS distortion parameters. "; fprint_generic_long_help(fw,is_wiki,grtrans_long_help,synopsis,description); return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { FILE *fr,*fw; int i,k,order,nvar,is_help,is_invert,is_ieee; char *infile,*outfile,*outtransfile,*intransfile, *colfitstr,*coloutstr,*colsdkstr,*colsdkoutstr, *wcsparam,*weightparam; wcsdata wcs_data,*wcs; int wcsconvert; colinfo col; int is_preserve_comments; fpoint *fps; point *ps; int nfp,niter,nt,padsize; double rejlevel; transformation tf_data,*tf=&tf_data; double ox,oy,scale; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; infile=outfile=intransfile=outtransfile=NULL; is_comment=is_verbose=is_help=is_ieee=0; colfitstr=coloutstr=colsdkstr=colsdkoutstr=NULL; wcsparam=NULL,wcsconvert=0; order=1; ox=oy=0.0,scale=1.0; col.refx=1,col.refy=2; col.nval=2; col.fitc=(int *)malloc(sizeof(int)*col.nval); col.fitc[0]=3, col.fitc[1]=4; col.outc=NULL; col.is=col.id=col.ik=-1; col.os=col.od=col.ok=-1; col.weight=0; weightparam=NULL; col.wgh_is_mag=0; col.wgh_power=1; niter=0;rejlevel=3.0; padsize=12;is_invert=0; is_preserve_comments=0; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help|--short-help|--help-short:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-i|--input:%s",&infile, "-o|--output:%s",&outfile, "-T|--input-transformation:%s",&intransfile, "--output-transformation:%s",&outtransfile, "-n|--iterations:%d",&niter, "-r|--sigma|--rejection|--rejection-level:%g",&rejlevel, "-w|--weight:%s",&weightparam, "--wcs:%s",&wcsparam, "-a|--order:%d",&order, "-f|--offset:%g,%g",&ox,&oy, "--scale:%g",&scale, "--colr|--col-ref|--col-xy:%d,%d",&col.refx,&col.refy, "--col-radec:" SNf(1) "%d,%d",&wcsconvert,&col.refx,&col.refy, "--col-pixel:" SNf(2) "%d,%d",&wcsconvert,&col.refx,&col.refy, "--coli|--col-fit:%s",&colfitstr, "--colo|--col-out:%s",&coloutstr, "--col-sdk:%s",&colsdkstr, "--col-out-sdk|--col-sdk-out:%s",&colsdkoutstr, "--col-weight:%d",&col.weight, "--preserve-comments:%f",&is_preserve_comments, "--padding:%d",&padsize, "--reverse|--inverse:%f",&is_invert, "--comment:%f",&is_comment,"(C):%f",&is_comment, /* "--ieee:%f",&is_ieee, */ "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-:%w",&infile, "-*|+*:%e", "*:%w",&infile, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"grtrans",FITSH_GRTRANS_VERSION,is_help); return(0); } else if ( 10 ) col.weight--; else col.weight=-1; if ( col.weight>=0 && weightparam != NULL ) { i=scanpar(weightparam,SCANPAR_DEFAULT, "magnitude:%f",&col.wgh_is_mag, "power:%g",&col.wgh_power, NULL); if ( i ) { fprint_error("invalid weighting parameter in '%s'",weightparam); return(1); } } if ( colfitstr != NULL ) { free(col.fitc); i=parse_number_list(colfitstr,&col.nval,&col.fitc); if ( i || col.nval<1 ) { fprint_error("invalid column specifications"); return(1); } for ( i=0 ; iinit.ra0=0.0; wcs->init.de0=0.0; wcs->init.type=WCS_TAN; wcs->init.order=1; wcs->init.zfactor=M_R2D; /* 180 \over \pi */ is_deg=is_rad=0; i=scanpar(wcsparam,SCANPAR_DEFAULT, "ra:%g" ,&wcs->init.ra0, "dec:%g",&wcs->init.de0, "tan:" SNf(WCS_TAN),&wcs->init.type, "sin:" SNf(WCS_SIN),&wcs->init.type, "arc:" SNf(WCS_ARC),&wcs->init.type, "order:%d",&wcs->init.order, "scale:%g",&wcs->init.zfactor, "deg|degree|degrees:%f",&is_deg, "rad|radian|radians:%f",&is_rad, NULL); if ( i ) { fprint_error("invalid WCS paramter in '%s'",wcsparam); return(1); } if ( is_deg ) wcs->init.zfactor=M_R2D; if ( is_rad ) wcs->init.zfactor=1.0; } else wcs=NULL; if ( intransfile != NULL || wcsconvert ) { if ( coloutstr != NULL ) { i=parse_number_list(coloutstr,&col.nval,&col.outc); if ( i || col.nval<1 ) { fprint_error("invalid output column specification"); return(1); } for ( i=0 ; iorder; nvar=(order+1)*(order+2)/2; xlin[0]=-ox/scale; xlin[1]=1.0/scale; xlin[2]=0.0; ylin[0]=-oy/scale; ylin[1]=0.0; ylin[2]=1.0/scale; tcoeff=(double *)malloc(sizeof(double)*nvar); for ( k=0 ; knval ; k++ ) { compose_2d_poly_with_affine(tf->vfits[k],order,xlin,ylin,tcoeff); for ( i=0 ; ivfits[k][i]=tcoeff[i]; } } free(tcoeff); fw=fopenwrite(outtransfile); if ( fw==NULL ) { fprint_error("unable to create output transformation file '%s'",outtransfile); return(1); } transformation_write_data(fw,tf,(is_comment?TRANS_WR_COMMENT:0)| TRANS_WR_DXDY|(is_ieee?TRANS_WR_IEEE_64:0)); fclosewrite(fw); } else if ( outtransfile != NULL ) { double **vfits; int nval,nrej; double fd,dd,s,sd,sdd,sig,w; fpoint *wf; nval=col.nval; if ( infile==NULL ) fr=stdin; else fr=fopenread(infile); if ( fr==NULL ) { fprint_error("unable to open input data file '%s'",infile); return(1); } read_data_points(fr,&col,&fps,&nfp); fclose(fr); if ( order<0 ) { fprint_error("invalid fit order"); return(1); } nvar=(order+1)*(order+2)/2; vfits=(double **)malloc(sizeof(double *)*nval); for ( k=0 ; k=0 && nrej ; nt-- ) { int fit_failed; for ( k=0,fit_failed=0 ; k0 ) { s=sdd=0.0; for ( i=0 ; ix,wf->y,order,vfits[k],ox,oy,scale)-wf->vals[k]; dd+=fd*fd; } wf->delta=sqrt(dd); s+=w; sdd+=dd*w; } sdd/=s; sig=sqrt(sdd); nrej=0; for ( i=0 ; idelta; if ( dd>rejlevel*sig ) { ps[i].weight=0.0; nrej++; } } } else nrej=0; } if ( outtransfile==NULL ) fw=stdout; else fw=fopenwrite(outtransfile); if ( fw==NULL ) { fprint_error("unable to create output transformation file '%s'",outtransfile); return(1); } if ( is_comment ) { fprintf(fw,"# Generated by grtrans\n"); } tf->type=TRANS_POLYNOMIAL; tf->order=order, tf->ox=ox,tf->oy=oy, tf->scale=scale; tf->vfits=vfits; tf->nval=nval; transformation_write_data(fw,tf,(is_comment?TRANS_WR_COMMENT:0)| TRANS_WR_DXDY|(is_ieee?TRANS_WR_IEEE_64:0)); if ( is_comment ) { s=sd=sdd=0.0; for ( i=0 ; inval; if ( col.nval != nval ) { fprint_error("column/dimension mismatch"); return(1); } if ( is_invert && nval != 2 ) { fprint_error("only 2D -> 2D transformations can be inverted"); return(1); } if ( infile==NULL ) fr=stdin; else fr=fopenread(infile); if ( fr==NULL ) { fprint_error("unable to open input data file '%s'",infile); return(1); } if ( outfile==NULL ) fw=stdout; else fw=fopenwrite(outfile); if ( fw==NULL ) { fprint_error("unable to create output data file '%s'",outfile); return(1); } jxx=jxy=jyx=jyy=NULL; if ( col.is>=0 ) { if ( nval != 2 ) col.is=col.id=col.ik=-1; else { transformation_get_jacobi(tf,&jxx,&jxy,&jyx,&jyy); } } if ( is_invert && jxx==NULL ) transformation_get_jacobi(tf,&jxx,&jxy,&jyx,&jyy); if ( is_invert && transformation_check_if_null(tf) ) { fprint_error("the transformation is definitely nil, cannot be inverted"); return(1); } npnt=(char **)malloc((nval+3)*sizeof(char *)); nstr=(char *)malloc((nval+3)*32); for ( k=0 ; kmxc ) mxc=col.outc[0]; if ( col.outc[1]>mxc ) mxc=col.outc[1]; } else { for ( k=0 ; korder,tf->vfits[k],tf->ox,tf->oy,tf->scale); sprintf(npnt[k],"%15.9g",nw); if ( col.outc[k]>mxc ) mxc=col.outc[k]; } } i=0;is=id=ik=0.0; if ( col.is>=0 && col.isorder-1,jxx,tf->ox,tf->oy,tf->scale); cjxy=eval_2d_poly(x,y,tf->order-1,jxy,tf->ox,tf->oy,tf->scale); cjyx=eval_2d_poly(x,y,tf->order-1,jyx,tf->ox,tf->oy,tf->scale); cjyy=eval_2d_poly(x,y,tf->order-1,jyy,tf->ox,tf->oy,tf->scale); if ( ! is_invert ) { cjdet=cjxx*cjyy-cjxy*cjyx; j11=+cjyy/cjdet; j12=+cjxy/cjdet; j21=+cjyx/cjdet; j22=+cjxx/cjdet; } else { j11=+cjxx; j12=-cjxy; j21=-cjyx; j22=+cjyy; } ma=j11*j11*sa+2*j11*j12*sb+j12*j12*sc; mb=j21*j11*sa+j21*j12*sb+j22*j11*sb+j22*j12*sc; mc=j21*j21*sa+2*j21*j22*sb+j22*j22*sc; ns=0.5*(ma+mc); nd=0.5*(ma-mc); nk=mb; sprintf(npnt[nval+0],"%12g",ns); sprintf(npnt[nval+1],"%12g",nd); sprintf(npnt[nval+2],"%12g",nk); if ( col.os>mxc ) mxc=col.os; if ( col.od>mxc ) mxc=col.od; if ( col.ok>mxc ) mxc=col.ok; /*fprintf(stderr,"mxc=%d\n",mxc);*/ } mxc++; for ( i=0 ; i x,y or x,y -> ra,dec */ { double ra,dec; char *rbuff,**cmd,*nstr,**npnt,*cpnt,outformat[8]; int n,nval,mxc; double x,y,z; wcs_get_projection_matrix(wcs->init.ra0,wcs->init.de0,wcs->init.mproj); if ( infile==NULL ) fr=stdin; else fr=fopenread(infile); if ( fr==NULL ) { fprint_error("unable to open input data file '%s'",infile); return(1); } nval=2; if ( col.nval != nval ) { fprint_error("column number must be 2 for WCS information extraction"); return(1); } if ( outfile==NULL ) fw=stdout; else fw=fopenwrite(outfile); if ( fw==NULL ) { fprint_error("unable to create output file '%s'",outfile); return(1); } npnt=(char **)malloc(nval*sizeof(char *)); nstr=(char *)malloc(nval*32); for ( k=0 ; k x,y */ { ra=x,dec=y; wcs_get_projected_coords_matrix(wcs->init.mproj,ra,dec,&x,&y,&z); wcs_project_distort(wcs->init.type,&x,&y,&z); /* note '-' sign here: */ sprintf(npnt[0],"%15.9g",-x*wcs->init.zfactor); sprintf(npnt[1],"%15.9g",+y*wcs->init.zfactor); } else /* x,y -> ra,dec */ { /* note '-' sign here: */ x=-x/wcs->init.zfactor; y=+y/wcs->init.zfactor; z=0.0; wcs_invert_project_distort(wcs->init.type,&x,&y,&z); ra=dec=0.0; wcs_invert_projected_coords_matrix(wcs->init.mproj,x,y,&ra,&dec); sprintf(npnt[0],"%15.9g",ra); sprintf(npnt[1],"%15.9g",dec); } mxc=0; if ( col.outc[0]>mxc ) mxc=col.outc[0]; if ( col.outc[1]>mxc ) mxc=col.outc[1]; mxc++; for ( i=0 ; iinit,wcs); fw=stdout; dump_wcs_headers(fw,wcs); free_wcs(wcs); } } return(0); } fitsh-0.9.2/src/ficonv.c0000644000175000017500000007516212771247720013516 0ustar apalapal/*****************************************************************************/ /* ficonv.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line user interface for (FITS) image convolution and subtraction. */ /*****************************************************************************/ #define FITSH_FICONV_VERSION "0.4" /*****************************************************************************/ #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "math/spline/spline.h" #include "math/spline/biquad.h" #include "math/spline/bicubic.h" #include "statistics.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "fitsmask.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "tensor.h" #include "common.h" #include "kernel.h" #include "history.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ int is_comment, /* write comments to some of the output files or not */ is_verbose; /* verbosity level */ char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ #define FM_NORMAL 0x00 #define FM_MASKED 0x01 #define FM_WEIGHTED 0x02 #define FM_BGITERATIVE 0x04 /*****************************************************************************/ int affine_img_transformation_spline_fit(fitsimage *ref,fitsimage *img,char **mask,int bx,int by,double *coeff) { int i,j,k,l,v,sx,sy,nvar; double **xbase,**ybase; double **xnspc,**ynspc; double *tmp,x,y; double **amatrix,*bvector,*fvars,f,w; if ( ref==NULL || img==NULL || coeff==NULL ) return(-1); else if ( (sx=ref->sx) != img->sx || (sy=ref->sy) != img->sy ) return(-1); else if ( bx<=0 || by<=0 ) return(-1); nvar=2*(bx+1)*(by+1); xbase=tensor_alloc_2d(double,sx,bx+1); ybase=tensor_alloc_2d(double,sy,by+1); xnspc=tensor_alloc_2d(double,bx+1,bx+1); ynspc=tensor_alloc_2d(double,by+1,by+1); tmp =tensor_alloc_1d(double,(bx>by?bx:by)+1); for ( i=0 ; i<=by ; i++ ) { for ( k=0 ; k<=by ; k++ ) { tmp[k]=0.0; } tmp[i]=1.0; natspline_coeff(tmp,by+1,ynspc[i]); for ( k=0 ; kdata[k][l]; for ( i=0 ; i<=by ; i++ ) { for ( j=0 ; j<=bx ; j++ ) { f=xbase[j][l]*ybase[i][k]; fvars[v+0]=f*w; fvars[v+1]=f; v+=2; } } for ( i=0 ; idata[k][l]; } } } solve_gauss(amatrix,bvector,nvar); for ( i=0 ; isx; sy=ref->sy; for ( k=0 ; kdata[k][l]=ref->data[k][l]*scl+off; } } tensor_free(bcoff); tensor_free(bcscl); return(0); } /*****************************************************************************/ char ** create_level_mask(fitsimage *img,char **inmask,double mlev1,double klev1,double mlev2,double klev2) { char **mask; double **bqc,*ps,sc,th1,th2; int i,j,sx,sy,np; sx=img->sx, sy=img->sy; bqc=(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); biquad_coeff(img->data,sx,sy,bqc,inmask); ps=tensor_alloc_1d(double,sx*sy); mask=fits_mask_duplicate(inmask,sx,sy); np=0; for ( i=0 ; i0.0 ) i=(int)((double)(np-1)*mlev1),th1=ps[i]*klev1; else th1=0.0; if ( klev2>0.0 ) i=(int)((double)(np-1)*mlev2),th2=ps[i]*klev2; else th2=0.0; tensor_free(ps); for ( i=0 ; i0.0 ) mask[i][j]=-1; else if ( sc>th2 && th2>0.0 ) mask[i][j]=+1; else mask[i][j]= 0; } } tensor_free(bqc); return(mask); } char ** create_foreground_mask(fitsimage *img,char **inmask,double mlev,double klev) { char **ret; ret=create_level_mask(img,inmask,0.0,0.0,mlev,klev); return(ret); } char ** create_background_mask(fitsimage *img,char **inmask,double mlev,double klev) { char **ret; int i,j; ret=create_level_mask(img,inmask,mlev,klev,0.0,0.0); for ( i=0 ; isy ; i++ ) { for ( j=0 ; jsx ; j++ ) { if ( ret[i][j]<0 ) ret[i][j]=1; } } return(ret); } double **create_image_weight(fitsimage *img,char **inmask) { double **bqc,**wght; int i,j,sx,sy; sx=img->sx,sy=img->sy; bqc=(double **)tensor_alloc_2d(double,2*sx+1,2*sy+1); biquad_coeff(img->data,sx,sy,bqc,inmask); wght=(double **)tensor_alloc_2d(double,sx,sy); if ( inmask==NULL ) { for ( i=0 ; ix1 ,r->y1 ,r->x2-1,r->y1 ,color,0x3333); fits_image_draw_line(img,r->x2-1,r->y1 ,r->x2-1,r->y2-1,color,0x3333); fits_image_draw_line(img,r->x2-1,r->y2-1,r->x1 ,r->y2-1,color,0x3333); fits_image_draw_line(img,r->x1 ,r->y2-1,r->x1 ,r->y1 ,color,0x3333); } return(0); } /*****************************************************************************/ int make_subtracted_image(fitsimage *cnv,char **mask,fitsimage *img,char **mask_img,fitsimage *out,char **mask_out,kernellist *xlist) { fitsimage xkcimg; int i,j,sx,sy; char **imask,**aimask; if ( cnv==NULL || cnv->data==NULL ) return(1); if ( img==NULL || img->data==NULL ) return(1); if ( out==NULL || out->data==NULL ) return(1); sx=cnv->sx,sy=cnv->sy; if ( xlist != NULL && xlist->kernels != 0 && xlist->nkernel>0 ) { kernel *k; int ihsize; ihsize=0; for ( i=0,k=xlist->kernels ; inkernel ; i++,k++ ) { if ( k->hsize > ihsize ) ihsize=k->hsize; } imask=aimask=fits_mask_expand_false(mask_img,sx,sy,ihsize,-1,-1,1); fits_image_duplicate(&xkcimg,img,1); convolve_with_kernel_set(img,imask,xlist,&xkcimg); } else { xkcimg.data=NULL; aimask=NULL; imask=mask_img; } for ( i=0 ; idata[i][j]=img->data[i][j]-cnv->data[i][j]; if ( xkcimg.data != NULL ) out->data[i][j]+=xkcimg.data[i][j]; mask_out[i][j]=0; } else { out->data[i][j]=0.0; mask_out[i][j]=-1; } } } if ( xkcimg.data != NULL ) fits_image_free(&xkcimg); if ( aimask != NULL ) fits_mask_free(aimask); return(0); } /*****************************************************************************/ int create_weights(fitsimage *img,char **mask,char **levmask,double **wcc,int sign) { int i,j,sx,sy; sx=img->sx,sy=img->sy; for ( i=0 ; i0 && levmask[i][j]>0 ) wcc[i][j]=1.0; else if ( sign<0 && levmask[i][j]<0 ) wcc[i][j]=1.0; else if ( sign==0 && levmask[i][j] ) wcc[i][j]=1.0; else wcc[i][j]=0.0; } } return(0); } int fit_kernels_native(fitsimage *ref,fitsimage *img,char **mask_conv, kernellist *klist,kernellist *xlist,int method,int bdc) { int i,j,l,sx,sy; kernel *bgkernel,*k; sx=ref->sx,sy=ref->sy; bgkernel=NULL; for ( i=0,k=klist->kernels ; inkernel ; i++,k++ ) { if ( k->type==KERNEL_BACKGROUND ) bgkernel=k; k->flag=1; } if ( xlist != NULL ) { for ( i=0,k=xlist->kernels ; inkernel ; i++,k++ ) { k->flag=1; } } if ( method & FM_WEIGHTED ) method|=FM_MASKED; /* -w implies -m ! */ if ( bgkernel != NULL && ( method & FM_MASKED ) ) { double **wcc,w; kernel *k; char **fgmask; wcc=tensor_alloc_2d(double,sx,sy); fgmask=create_foreground_mask(ref,mask_conv,0.5,3.0); for ( i=0 ; inkernel ; i++ ) { k=&klist->kernels[i];k->flag=1; } l=0; for ( i=0 ; idata[i][j]; else w=1.0; wcc[i][j]=w; l++; } else wcc[i][j]=0.0; } } logmsg(is_verbose>=1,"Foreground pixels: %d/%d\n",l,sx*sy); fit_kernel_poly_coefficients_block(ref,img,mask_conv,wcc,bdc,bdc,klist,xlist); fits_mask_free(fgmask); tensor_free(wcc); } else fit_kernel_poly_coefficients_block(ref,img,mask_conv,NULL,bdc,bdc,klist,xlist); return(0); } int fit_kernels(fitsimage *ref,char **mask_ref,fitsimage *img,char **mask_img, char **inmask,kernellist *klist,kernellist *xlist,int method,int bdc, int niter,double rlevel,double gain) { int hsize,i,sx,sy; char **mask,**mask_conv; kernel *k; if ( ref==NULL || img==NULL ) return(1); if ( ref->data==NULL || img->data==NULL ) return(1); sx=ref->sx,sy=ref->sy; if ( sx != img->sx || sy != img->sy ) return(1); if ( xlist==NULL || xlist->nkernel<=0 || xlist->kernels==NULL ) xlist=NULL; logmsg(is_verbose>=1,"Fitting kernel coefficients ...\n"); hsize=0; for ( i=0,k=klist->kernels ; inkernel ; i++,k++ ) { if ( k->hsize > hsize ) hsize=k->hsize; } if ( xlist != NULL ) { for ( i=0,k=xlist->kernels ; k != NULL && inkernel ; i++,k++ ) { if ( k->hsize > hsize ) hsize=k->hsize; } } mask=fits_mask_create_empty(sx,sy); fits_mask_and(mask,sx,sy,mask_img); fits_mask_and(mask,sx,sy,mask_ref); if ( inmask != NULL ) fits_mask_and(mask,sx,sy,inmask); mask_conv=fits_mask_expand_false(mask,sx,sy,hsize,-1,-1,1); if ( niter<=0 ) niter=1; else niter++; while ( niter>0 ) { fit_kernels_native(ref,img,mask_conv,klist,xlist,method,bdc); niter--; if ( niter>0 ) { fitsimage sub; int i,j,rej,tot; char **ms; double s,s2,w,n,sig,nz; ms=mask_conv; fits_image_duplicate(&sub,ref,1); convolve_to_subtracted(ref,img,ms,klist,xlist,&sub); n=s=s2=0.0; for ( i=0 ; idata[i][j]/gain); if ( fabs(sub.data[i][j])>rlevel*nz ) ms[i][j]=0,rej++; } } logmsg(is_verbose>=1,"Rejected: %d from %d\n",rej,tot); fits_image_free(&sub); } }; tensor_free(mask_conv); fits_mask_free(mask); return(0); } /*****************************************************************************/ int stamp_parse_argument(char *stamparg,char **fitmask,int sx,int sy) { char *tmpstamparg,**cmd; int k,ix,iy,is,i,j; double x,y,s; tmpstamparg=strdup(stamparg); cmd=tokenize_char_dyn(tmpstamparg,':'); for ( k=0 ; cmd != NULL && cmd[k] != NULL ; k++ ) { if ( sscanf(cmd[k],"%lg,%lg,%lg",&x,&y,&s)<3 ) continue; if ( s<=0.0 ) continue; ix=(int)x, iy=(int)y; is=(int)s; for ( i=iy-is ; i<=iy+is ; i++ ) { if ( i<0 || i>=sy ) continue; for ( j=ix-is ; j<=ix+is ; j++ ) { if ( j<0 || j>=sx ) continue; fitmask[i][j] |= 0x80; } } } for ( i=0 ; i=sy ) continue; for ( j=ix-is ; j<=ix+is ; j++ ) { if ( j<0 || j>=sx ) continue; fitmask[i][j] |= 0x80; } } } for ( i=0 ; i] [-i \n" "\t[-m|--masked [-w|--weighted]] [-b|--background-iterative]\n" "\t[-n|--iterations ] [-s|--rejection-level ]]\n" "\t{--input-kernel |-k \"\"}\n" "\t[--output-kernel ]\n"); fprintf(fw, "\t[--input-extra-kernel |-x \"\"]" "\t[--output-extra-kernel ]\n" "\t[-o|--output ]\n" "\t[--output-subtracted ]\n" "\t[-a ] [-d|--divide ]\n" "\t[-t|--stamp[s] ,,[:,,...]]\n" "\t[--input-stamps ]\n"); return(0); } longhelp_entry ficonv_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-r, --input-reference ", "Name of the reference FITS image file." }, { "-i, --input ", "Name of the input FITS image file (required only for kernel fitting)." }, { "-k, --kernel ", "List of kernel bases used for fitting convolution kernel." "See also \"Kernel specifications\" below for the format of this " " argument." }, { "--input-kernel ", "Name of the file containing kernel bases. The kernel bases in this " "file should have no associated coefficients if convolution fitting " "is done, otherwise the kernel basis file must contain the " "convolution coefficients" }, { "--output-kernel ", "Name of the file where the coefficients for the kernel bases are " "stored after convolution kernel fitting" }, { "-o, -oc, --output, --output-convolved ", "Name of the output file which is the reference image convolved with " "the kernel solution (which can either be a previously fitted and now " "read from a file or the result of the current fit)" }, { "--output-subtracted ", "The difference between the input image and the convolved reference " "image." }, { "-a, --add-to ", "This optionally specified file is added to the convolved image" }, { "-M, --input-mask ", "Input mask file to co-add to output image mask." }, { "-n, --iterations ", "Use an iterative fit with the rejection of the outlier pixels." "The maximum number of iterations should be specified with this " "command line argument" }, { "-s, --rejection-level ", "Rejection level in standard deviation units." }, { "Kernel specifications (each separated with a semi-colon, \";\"):", NULL }, { "i/", "identity kernel (a.k.a. \"flux term\") with the specified order " "of polynomial spatial variations" }, { "b/", "constant offset kernel (a.k.a. \"background term\") with the " "specified order of polynomial spatial variations" }, { "d=/", "discrete kernel with the half-size of and the specified " "order of polynomial spatial variations" }, { "g=,,/", "Gaussian kernel with the half-size of , standard deviation " "of and Hermite basis order of , with the specified " "order of polynomial spatial variations" }, { NULL, NULL } }; int fprint_ficonv_long_help(FILE *fw,int is_wiki) { char *synopsis= "ficonv [options] [-r ] [-i ] [-o ]"; char *description= __extension__ "The purpose of this program is twofold. First, using a reference and input " "FITS image, the program tries to figure out the best-fit convolution kernel " "which transforms the reference image to the input image. The convolution " "kernel solution is saved as a separate, human-readable file. Second, using " "an existing such kernel solution file, `ficonv` convolves the reference " "image and optionally co-adds an additional image to the result. " "The program figures out the desired mode (i.e. whether to fit a convolution " "kernel or use an existing kernel solution to convolve an image) from the " "presence or lack of the command line options."; fprint_generic_long_help(fw,is_wiki,ficonv_long_help,synopsis,description); return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { int i,j,sx,sy,bdc; int is_help,method,niter; double gain,rejectlevel; int psx,psy; char *imgname,*refname,*ikname,*okname,*ixname,*oxname, *oconvname,*osubname,*addname,**inmasklist,*kernelarg, *stamparg,*stampfile,*splinestampfile,*xkarg; kernellist klist_data,*klist=&klist_data, xlist_data,*xlist=&xlist_data; fits *img,*refimg,*outimg; char **mask_img,**mask_ref,**inmask,**fitmask,**spfmask; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; is_comment=is_verbose=is_help=0; addname=imgname=refname=ikname=okname=ixname=oxname=oconvname=osubname=NULL; stamparg=kernelarg=xkarg=NULL; inmasklist=NULL; stampfile=splinestampfile=NULL; method=0; gain=0.0; niter=0;rejectlevel=3.0; bdc=32; psx=psy=-1; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-o|--output|--output-convolved:%s",&oconvname, "-g|--gain:%g",&gain, "--output-subtracted:%s",&osubname, "-i|--input|-f|--fit:%s",&imgname, "-M|--input-mask:%t",&inmasklist, "-r|--reference:%s",&refname, "-a|--add-to:%s",&addname, "-t|--stamp|--stamps:%s",&stamparg, "--input-stamp|--input-stamps:%s",&stampfile, "-p|--pre-spline:%d,%d",&psx,&psy, "--input-spline-stamp|--input-spline-stamps:%s",&splinestampfile, "--input-kernel-list:%s",&ikname, "--output-kernel-list:%s",&okname, "-k|--kernel:%s",&kernelarg, "--input-extra-kernel-list:%s",&ixname, "--output-extra-kernel-list:%s",&oxname, "-x|--extra-kernel:%s",&xkarg, "-m|--masked:%0f",&method, "-w|--weighted:%1f",&method, "-b|--background-iterative:%2f",&method, "-n|--iterations:%d",&niter, "-s|--rejection-level:%g",&rejectlevel, "-d|--divide:%d",&bdc, "--comment:%f",&is_comment,"(C):%f",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "*:%e", NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"ficonv",FITSH_FICONV_VERSION,is_help); return(0); } else if ( 1i.dim != 2 ) { fprint_error("input image: mage is not a 2D one"); return(1); } if ( img->i.sx <= 0 || img->i.sy <= 0 ) { fprint_error("input image: invalid/unexpected size"); return(1); } if ( fits_rescale(img) ) { fprint_error("input image: unable to rescale image"); return(1); } sx=img->i.sx, sy=img->i.sy; } if ( refname != NULL ) { FILE *fr; fr=fopenread(refname); if ( fr==NULL ) { fprint_error("reference image: unable to open file '%s'",imgname); return(1); } refimg=fits_read(fr); fcloseread(fr); if ( refimg==NULL ) { fprint_error("reference image: unable to read image contents"); return(1); } if ( refimg->i.dim != 2 ) { fprint_error("reference image: mage is not a 2D one"); return(1); } if ( refimg->i.sx <=0 || refimg->i.sy <= 0 ) { fprint_error("reference image: invalid/unexpected size"); return(1); } if ( fits_rescale(refimg) ) { fprint_error("reference image: unable to rescale image"); return(1); } if ( img != NULL && ( refimg->i.sx != sx || refimg->i.sy != sy ) ) { fprint_error("reference and input image sizes differ"); return(1); } sx=refimg->i.sx, sy=refimg->i.sy; } if ( refimg != NULL && gain<=0.0 ) fits_get_gain(refimg,&gain); if ( gain<=0.0 ) gain=1.0; if ( inmasklist != NULL ) { inmask=fits_mask_create_empty(sx,sy); if ( join_masks_from_files(inmask,sx,sy,inmasklist) ) { fprint_error("unable to read one of the input mask files"); return(1); } } else inmask=NULL; if ( stamparg != NULL ) { fitmask=fits_mask_create_empty(sx,sy); stamp_parse_argument(stamparg,fitmask,sx,sy); } else if ( stampfile != NULL ) { FILE *fr; fitmask=fits_mask_create_empty(sx,sy); fr=fopenread(stampfile); if ( fr==NULL ) { fprint_error("stamp file: unable to open file '%s'", stampfile); return(1); } stamp_read_file(fr,fitmask,sx,sy); fcloseread(fr); } else fitmask=NULL; if ( splinestampfile != NULL && psx>0 && psy>0 ) { FILE *fr; spfmask=fits_mask_create_empty(sx,sy); fr=fopenread(splinestampfile); if ( fr==NULL ) { fprint_error("spline stamp file: unable to open file '%s'",splinestampfile); return(1); } stamp_read_file(fr,spfmask,sx,sy); fcloseread(fr); } else spfmask=NULL; if ( sx>0 && sy>0 ) logmsg(is_verbose>=1,"[%d,%d]\n",sx,sy); if ( kernelarg != NULL && ikname != NULL ) { fprint_error("ambiguous kernel definitions"); return(1); } if ( xkarg != NULL && ixname != NULL ) { fprint_error("ambiguous reference kernel definitions"); return(1); } if ( kernelarg == NULL && ikname == NULL ) { fprint_error("convolution information is not known/specified"); return(1); } if ( xkarg == NULL && ixname == NULL ) oxname=NULL; /* ignore -ox if -ix or -x is not specified */ if ( addname != NULL && imgname != NULL ) { fprint_error("invalid combination of input image specifications"); return(1); } klist->nkernel=0, klist->kernels=NULL; if ( kernelarg != NULL ) { int r; r=create_kernels_from_kernelarg(kernelarg,klist); klist->type=0; if ( r ) { fprint_error("unable to parse kernel specification list"); return(1); } } if ( ikname != NULL ) { FILE *fr; int r; fr=fopenread(ikname); if ( fr==NULL ) { fprint_error("unable to open input kernel list file '%s'",ikname); return(1); } r=kernel_info_read(fr,klist); fcloseread(fr); if ( r ) { fprint_error("unable to read or parse contents of input kernel list file '%s'",ikname); return(1); } } for ( i=0 ; inkernel ; i++ ) { klist->kernels[i].target=0; } xlist->nkernel=0; xlist->kernels=NULL; if ( xkarg != NULL ) { int r; r=create_kernels_from_kernelarg(xkarg,xlist); xlist->type=0; if ( r ) { fprint_error("unable to parse reference kernel specification list"); return(1); } } if ( ixname != NULL ) { FILE *fr; int r; fr=fopenread(ixname); if ( fr==NULL ) { fprint_error("unable to open reference kernel list file '%s'",ixname); return(1); } r=kernel_info_read(fr,xlist); fcloseread(fr); if ( r ) { fprint_error("unable to read or parse contents of reference kernel list file '%s'",ixname); return(1); } } for ( i=0 ; xlist->kernels != NULL && inkernel ; i++ ) { xlist->kernels[i].target=1; } logmsg(is_verbose>=1,"Number of kernels: %d+%d.\n",klist->nkernel,xlist->nkernel); kernel_init_images(klist); kernel_init_images(xlist); if ( img != NULL ) mask_img=fits_mask_read_from_header(&img->header,sx,sy,NULL); else mask_img=NULL; if ( refimg != NULL ) mask_ref=fits_mask_read_from_header(&refimg->header,sx,sy,NULL); else mask_ref=NULL; /****************************************************************************/ if ( img != NULL && refimg != NULL ) { if ( klist->type != 0 ) { fprint_error("kernel specification contains fitted amplitudes"); return(1); } if ( psx>0 && psy>0 ) { double *coeff; if ( spfmask==NULL ) spfmask=fits_mask_create_empty(sx,sy); if ( inmask != NULL ) fits_mask_and(spfmask,sx,sy,inmask); fits_mask_and(spfmask,sx,sy,mask_ref); fits_mask_and(spfmask,sx,sy,mask_img); coeff=(double *)malloc(sizeof(double)*2*(psx+1)*(psy+1)); affine_img_transformation_spline_fit(&img->i,&refimg->i,spfmask,psx,psy,coeff); affine_img_transformation_spline_eval(&img->i,mask_img,psx,psy,coeff); free(coeff); } if ( fitmask==NULL ) fitmask=fits_mask_create_empty(sx,sy); if ( inmask != NULL ) fits_mask_and(fitmask,sx,sy,inmask); fit_kernels(&refimg->i,mask_ref,&img->i,mask_img,fitmask,klist,xlist,method,bdc,niter,rejectlevel,gain); } if ( fitmask != NULL ) { fits_mask_free(fitmask); fitmask=NULL; } if ( spfmask != NULL ) { fits_mask_free(spfmask); spfmask=NULL; } if ( refimg != NULL && ( oconvname != NULL || osubname != NULL ) ) { int hsize; char **mask,**mask_conv; logmsg(is_verbose>=1,"Convolving ...\n"); if ( ! klist->type ) { fprint_error("kernel specification lacks amplitudes"); return(1); } hsize=0; for ( i=0 ; inkernel ; i++ ) { if ( klist->kernels[i].type==KERNEL_BACKGROUND || klist->kernels[i].type==KERNEL_IDENTITY ) continue; if ( klist->kernels[i].hsize > hsize ) hsize=klist->kernels[i].hsize; } mask=fits_mask_create_empty(sx,sy); fits_mask_and(mask,sx,sy,mask_ref); if ( inmask != NULL ) fits_mask_and(mask,sx,sy,inmask); mask_conv=fits_mask_expand_false(mask,sx,sy,hsize,-1,-1,1); outimg=fits_duplicate_empty(refimg); convolve_with_kernel_set(&refimg->i,mask_conv,klist,&outimg->i); if ( addname != NULL ) { FILE *fr; fits *addimg; char **addmask; while ( 1 ) { fr=fopenread(addname); if ( fr == NULL ) break; addimg=fits_read(fr); fcloseread(fr); if ( addimg==NULL ) break; if ( addimg->i.data==NULL || addimg->i.sx != sx || addimg->i.sy != sy || addimg->i.dim != 2 ) break; if ( fits_rescale(addimg) ) break; addmask=fits_mask_read_from_header(&addimg->header,sx,sy,NULL); for ( i=0 ; ii.data[i][j]+=addimg->i.data[i][j], mask[i][j]=0; else mask[i][j]=-1; } } fits_mask_free(addmask); break; }; } else { for ( i=0 ; ii,mask,outimg->i.bit,1,MASK_OVERSATURATED,MASK_OVERSATURATED); fits_mask_export_as_header(&outimg->header,1,mask,sx,sy,NULL); fits_write(fw,outimg); fclosewrite(fw); } if ( osubname != NULL && img != NULL ) { FILE *fw; make_subtracted_image(&outimg->i,mask,&img->i,mask_img,&outimg->i,mask,xlist); fw=fopenwrite(osubname); if ( fw==NULL ) { fprint_error("unable to create output subtracted image '%s'",osubname); return(1); } fits_copy_full_header(outimg,img); fits_mask_export_as_header(&outimg->header,1,mask,sx,sy,NULL); fits_write(fw,outimg); fclosewrite(fw); } fits_mask_free(mask_conv); fits_mask_free(mask); } if ( okname != NULL ) { FILE *fw; fw=fopenwrite(okname); if ( fw==NULL ) { fprint_error("unable to create output kernel list file '%s'",okname); return(1); } kernel_info_write(fw,klist); fclosewrite(fw); } if ( oxname != NULL ) { FILE *fw; fw=fopenwrite(oxname); if ( fw==NULL ) { fprint_error("unable to create output reference kernel list file '%s'",oxname); return(1); } kernel_info_write(fw,xlist); fclosewrite(fw); } if ( mask_ref != NULL ) fits_mask_free(mask_ref); if ( mask_img != NULL ) fits_mask_free(mask_img); if ( inmask != NULL ) fits_mask_free(inmask); return(0); } fitsh-0.9.2/src/magnitude.c0000644000175000017500000000274111021353620014160 0ustar apalapal/*****************************************************************************/ /* magnitude.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Some simple functions which converts between magnitudes and fluxes. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include "magnitude.h" /*****************************************************************************/ double mag_to_flux(double mag,magflux *mf) { double flux; flux=mf->intensity*exp(-0.4*M_LN10*(mag-mf->magnitude)); return(flux); } double flux_to_mag(double flux,magflux *mf) { double mag; if ( flux<=0.0 || mf->intensity<=0 ) return(0.0); else { mag=(-2.5*log10(flux/mf->intensity))+mf->magnitude; return(mag); } } /*****************************************************************************/ int flux_to_mag_magerr(double f,double fe,magflux *mf,double *rm,double *rme) { double mg,me; int ret; if ( f <= 0.0 || mf->intensity <= 0.0 ) { mg=0.0, me=0.0; ret=1; } else { mg=flux_to_mag(f,mf); me=1.08574 * (fabs(fe)/f); /* 1.08574... = 5/ln(100) */ ret=0; } if ( rm != NULL ) *rm =mg; if ( rme != NULL ) *rme=me; return(ret); } /*****************************************************************************/ fitsh-0.9.2/src/firandom.h0000644000175000017500000000660012766337426014034 0ustar apalapal/*****************************************************************************/ /* firandom.h */ /*****************************************************************************/ #ifndef __FIRANDOM_H_INCLUDED #define __FIRANDOM_H_INCLUDED 1 #include "magnitude.h" /*****************************************************************************/ #define VAR_X 0 #define VAR_Y 1 #define VAR_AX 2 #define VAR_AY 3 #define VAR_I 4 #define VAR_M 5 #define VAR_SH_F 6 #define VAR_SH_E 7 #define VAR_SH_P 8 #define VAR_SN_S 9 #define VAR_SN_D 10 #define VAR_SN_K 11 #define VAR_SI_S 12 #define VAR_SI_D 13 #define VAR_SI_K 14 #define MSK_X (1< #include #include #include #include #include #include #include "fitsh.h" #include "fitsmask.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "statistics.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "magnitude.h" #include "imgtrans.h" #include "tensor.h" #include "common.h" #include "stars.h" #include "fistar.h" /*****************************************************************************/ static char *wrninappr="Warning: inappropriate content in line %d, skipped.\n"; int read_star_candidates(FILE *fr,colinfo *col,initcand **ricands,int *rnicand,magflux *mf) { initcand *icands,*wic; int nicand,n,ln; char *rbuff,**cmd; double rx,ry,rs,rd,rk,rf,rb; icands=NULL; nicand=0; rbuff=NULL;cmd=NULL;ln=0; while ( ! feof(fr) ) { if ( rbuff != NULL ) { free(rbuff);rbuff=NULL; } if ( cmd != NULL ) { free(cmd); cmd=NULL; } rbuff=freadline(fr); if ( rbuff==NULL ) break; ln++; remove_newlines_and_comments(rbuff); if ( rbuff[0]==0 ) break; cmd=tokenize_spaces_dyn(rbuff); if ( cmd==NULL ) break; for ( n=0 ; cmd[n] != NULL ; ) n++; if ( col->x>=n || col->y>=n ) { fprintf(stderr,wrninappr,ln);continue; } if ( sscanf(cmd[col->x],"%lg",&rx)<1 || sscanf(cmd[col->y],"%lg",&ry)<1 ) { fprintf(stderr,wrninappr,ln);continue; } if ( ! isfinite(rx) || ! isfinite(ry) ) { fprintf(stderr,wrninappr,ln);continue; } rs=rd=rk=0.0; rf=0.0; rb=0.0; if ( 0<=col->s ) { if ( col->s>=n || sscanf(cmd[col->s],"%lg",&rs)<1 ) { fprintf(stderr,wrninappr,ln);continue; } } if ( 0<=col->d && 0<=col->k ) { if ( col->d>=n || col->k>=n ) { fprintf(stderr,wrninappr,ln);continue; } if ( sscanf(cmd[col->d],"%lg",&rd)<1 || sscanf(cmd[col->k],"%lg",&rk)<1 ) { fprintf(stderr,wrninappr,ln);continue; } } if ( ! isfinite(rs) || ! isfinite(rd) || ! isfinite(rk) ) { fprintf(stderr,wrninappr,ln);continue; } if ( 0<=col->flux ) { if ( col->flux>=n || sscanf(cmd[col->flux],"%lg",&rf)<1 ) { fprintf(stderr,wrninappr,ln);continue; } } else if ( 0<=col->mag ) { if ( col->mag>=n || sscanf(cmd[col->mag],"%lg",&rf)<1 ) { fprintf(stderr,wrninappr,ln);continue; } rf=mag_to_flux(rf,mf); } if ( 0<=col->bg ) { if ( col->bg>=n || sscanf(cmd[col->bg],"%lg",&rb)<1 ) { fprintf(stderr,wrninappr,ln);continue; } } icands=(initcand *)realloc(icands,sizeof(initcand)*(nicand+1)); wic=&icands[nicand]; wic->x=rx,wic->y=ry; wic->s=rs, wic->d=rd, wic->k=rk; wic->bg=rb; wic->flux=rf; nicand++; }; if ( rbuff != NULL ) free(rbuff); if ( cmd != NULL ) free(cmd); if ( ricands != NULL ) *ricands=icands; if ( rnicand != NULL ) *rnicand=nicand; return(0); } /*****************************************************************************/ int read_input_position_list(FILE *fr,colinfo *col,iposition **rips,int *rnip) { iposition *ips; int nip,ln,n; char *rbuff,**cmd; double dx,dy; rbuff=NULL; cmd=NULL; ips=NULL; nip=0; ln=0; while ( ! feof(fr) ) { if ( rbuff != NULL ) { free(rbuff);rbuff=NULL; } if ( cmd != NULL ) { free(cmd); cmd=NULL; } rbuff=freadline(fr); if ( rbuff==NULL ) break; ln++; remove_newlines_and_comments(rbuff); if ( rbuff[0]==0 ) continue; cmd=tokenize_spaces_dyn(rbuff); if ( cmd==NULL ) continue; for ( n=0 ; cmd[n] != NULL ; ) n++; if ( col->x>=n || col->y>=n ) continue; if ( sscanf(cmd[col->x],"%lg",&dx)<1 || sscanf(cmd[col->y],"%lg",&dy)<1 ) continue; ips=(iposition *)realloc(ips,sizeof(iposition)*(nip+1)); if ( col->idid]); else ips[nip].name=NULL; ips[nip].x=dx; ips[nip].y=dy; nip++; } if ( rbuff != NULL ) free(rbuff); if ( cmd != NULL ) free(cmd); if ( rips != NULL ) *rips=ips; if ( rnip != NULL ) *rnip=nip; return(0); } /*****************************************************************************/ int draw_mark_star_pixels(fitsimage *img,star *stars,int nstar) { int n,i,ix,iy; candidate *wc; for ( n=0 ; nnipoint==0 || wc->ipoints==NULL ) continue; for ( i=0 ; inipoint ; i++ ) { ix=wc->ipoints[i].x, iy=wc->ipoints[i].y; img->data[iy][ix]=0.0; } } return(0); } int draw_mark_stars(fitsimage *img,star *stars,int nstar,int msym,int msize) { int i,ix,iy; double color; color=0.0; for ( i=0 ; iix,iy=stars[i].cand->iy; switch ( msym ) { case MARK_SYM_DOTS: fits_image_draw_pixel(img,ix,iy,color); break; case MARK_SYM_SQUARES: fits_image_draw_line(img,ix-msize,iy-msize,ix+msize,iy-msize,color,-1); fits_image_draw_line(img,ix+msize,iy-msize,ix+msize,iy+msize,color,-1); fits_image_draw_line(img,ix+msize,iy+msize,ix-msize,iy+msize,color,-1); fits_image_draw_line(img,ix-msize,iy+msize,ix-msize,iy-msize,color,-1); break; case MARK_SYM_CIRCLES: fits_image_draw_circle(img,ix,iy,msize,color); break; } } return(0); } /*****************************************************************************/ typedef struct { int n; magflux *mf; } formatoutparam; typedef struct { int id; int width; char *comment; int (*fprint)(FILE *fw,star *s,formatoutparam *fop); char *tlist[7]; } formatname; static int fprint_star_id(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6d ",fop->n+1); return(0); } static int fprint_star_ix(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%4s ","-"); else fprintf(fw,"%4d ",s->cand->ix+1); return(0); } static int fprint_star_iy(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%4s ","-"); else fprintf(fw,"%4d ",s->cand->iy+1); return(0); } static int fprint_star_cx(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%8s ","-"); else fprintf(fw,"%8.3f ",s->cand->cx); return(0); } static int fprint_star_cy(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%8s ","-"); else fprintf(fw,"%8.3f ",s->cand->cy); return(0); } static int fprint_star_cbg(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%8s ","-"); else fprintf(fw,"%8.2f ",s->cand->bg); return(0); } static int fprint_star_camp(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%8s ","-"); else fprintf(fw,"%8.2f ",s->cand->amp); return(0); } static int fprint_star_cmax(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%8s ","-"); else fprintf(fw,"%8.2f ",s->cand->peak); return(0); } static int fprint_star_cdevs(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%6s ","-"); else fprintf(fw,"%6.3f ",0.5*(s->cand->sxx+s->cand->syy)); return(0); } static int fprint_star_cdevd(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%6s ","-"); else fprintf(fw,"%6.3f ",0.5*(s->cand->sxx-s->cand->syy)); return(0); } static int fprint_star_cdevk(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%6s ","-"); else fprintf(fw,"%6.3f ",s->cand->sxy); return(0); } static int fprint_star_x(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.3f ",s->location.gcx); return(0); } static int fprint_star_y(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.3f ",s->location.gcy); return(0); } static int fprint_star_bg(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.2f ",s->location.gbg); return(0); } static int fprint_star_amp(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.2f ",s->location.gamp); return(0); } static int fprint_star_dsig(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",s->gsig); return(0); } static int fprint_star_ddel(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",s->gdel); return(0); } static int fprint_star_dkap(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",s->gkap); return(0); } static int fprint_star_fwhm(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%5.3f ",s->gfwhm); return(0); } static int fprint_star_ellip(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%5.3f ",s->gellip); return(0); } static int fprint_star_pa(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%5.1f ",s->gpa); return(0); } static int fprint_star_devs(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",s->shape.gs); return(0); } static int fprint_star_devd(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",s->shape.gd); return(0); } static int fprint_star_devk(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",s->shape.gk); return(0); } static int fprint_star_devl(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",s->shape.gl); return(0); } static int fprint_star_flux(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%10.2f ",s->flux); return(0); } static int fprint_star_mag(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%9.3f ",flux_to_mag(s->flux,fop->mf)); return(0); } static int fprint_star_noise(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%8s ","-"); else fprintf(fw,"%8.2f ",s->cand->noise); return(0); } static int fprint_star_sn(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%8s ","-"); else if ( s->cand->noise>0.0 ) fprintf(fw,"%8.1f ",s->flux/s->cand->noise); else fprintf(fw,"%8s ","-"); return(0); } static int fprint_star_cpix(FILE *fw,star *s,formatoutparam *fop) { if ( s->cand==NULL ) fprintf(fw,"%5s ","-"); else fprintf(fw,"%5d ",s->cand->nipoint); return(0); } static int fprint_star_mom(FILE *fw,star *s,formatoutparam *fop) { int i; double m; for ( i=3 ; i<(s->shape.order+1)*(s->shape.order+2)/2 ; i++ ) { m=s->shape.mom[i-3]; if ( i==3 ) fprintf(fw,"%+.4f",m); else fprintf(fw,",%+.4f",m); } return(0); } static int fprint_star_px(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.3f ",s->psf.gcx); return(0); } static int fprint_star_py(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.3f ",s->psf.gcy); return(0); } static int fprint_star_pbg(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.2f ",s->psf.gbg); return(0); } static int fprint_star_pamp(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%8.2f ",s->psf.gamp); return(0); } static int fprint_star_pmoms(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",1.0); return(0); } static int fprint_star_pmomx(FILE *fw,star *s,formatoutparam *fop) { fprintf(fw,"%6.3f ",0.0); return(0); } static formatname formatnames[] = { { I_EMPTY, 1, "-", NULL, { "-", NULL } }, { I_ID, 6, "Ident", fprint_star_id, { "id", NULL } }, { I_IX, 4, "IX", fprint_star_ix, { "ix", NULL } }, { I_IY, 4, "IY", fprint_star_iy, { "iy", NULL } }, { I_CX, 8, "C.X", fprint_star_cx, { "cx", NULL } }, { I_CY, 8, "C.Y", fprint_star_cy, { "cy", NULL } }, { I_CBG, 8, "C.Bg", fprint_star_cbg, { "cbg", NULL } }, { I_CAMP, 8, "C.Amp", fprint_star_camp, { "camp", NULL } }, { I_CMAX, 8, "C.Max", fprint_star_cmax, { "cmax", NULL } }, { I_CPIX, 5, "NPix", fprint_star_cpix, { "cpix", "pix", "npix", NULL } }, { I_CDEVS, 6, "C.S", fprint_star_cdevs, { "cs", NULL } }, { I_CDEVD, 6, "C.D", fprint_star_cdevd, { "cd", NULL } }, { I_CDEVK, 6, "C.K", fprint_star_cdevk, { "ck", NULL } }, { I_X, 8, "X", fprint_star_x, { "x", NULL } }, { I_Y, 8, "Y", fprint_star_y, { "y", NULL } }, { I_BG, 8, "Bg", fprint_star_bg, { "b", "bg", "background", NULL } }, { I_AMP, 8, "Amp", fprint_star_amp, { "a", "amp", "amplitude", NULL } }, { I_DEVS, 6, "S", fprint_star_devs, { "s", NULL } }, { I_DEVD, 6, "D", fprint_star_devd, { "d", NULL } }, { I_DEVK, 6, "K", fprint_star_devk, { "k", NULL } }, { I_MOM, 8, "Coeff", fprint_star_mom, { "mom", "moments", NULL } }, { I_DEVL, 6, "L", fprint_star_devl, { "l", NULL } }, { I_DSIG, 6, "sigma", fprint_star_dsig, { "sig", "sigma", NULL } }, { I_DDEL, 6, "delta", fprint_star_ddel, { "del", "delta", NULL } }, { I_DKAP, 6, "kappa", fprint_star_dkap, { "kap", "kappa", NULL } }, { I_FWHM, 5, "FWHM", fprint_star_fwhm, { "f", "fwhm", NULL } }, { I_ELLIP, 5, "Ellip", fprint_star_ellip, { "e", "ellip", NULL } }, { I_PA, 5, "P.A.", fprint_star_pa, { "p", "pa", NULL } }, { I_FLUX, 10, "Flux", fprint_star_flux, { "i", "flux", NULL } }, { I_MAG, 9, "Magnitude",fprint_star_mag, { "m", "mag", "magnitude", NULL } }, { I_NOISE, 8, "Noise", fprint_star_noise, { "noise", NULL } }, { I_SN, 8, "S/N", fprint_star_sn, { "sn", "spern", "s/n", NULL } }, { I_PX, 8, "PSF.X", fprint_star_px, { "px", NULL } }, { I_PY, 8, "PSF.Y", fprint_star_py, { "py", NULL } }, { I_PBG, 8, "PSF.Bg", fprint_star_pbg, { "pbg", NULL } }, { I_PAMP, 8, "PSF.Amp", fprint_star_pamp, { "pamp", NULL } }, { I_PMOMS, 6, "PSF.S", fprint_star_pmoms, { "ps", NULL } }, { I_PMOMD, 6, "PSF.D", fprint_star_pmomx, { "pd", NULL } }, { I_PMOMK, 6, "PSF.K", fprint_star_pmomx, { "pk", NULL } }, { I_PMOML, 6, "PSF.L", fprint_star_pmomx, { "pl", NULL } }, { -1, 0, NULL, NULL, { NULL } } }; int *output_format_stars(char *iformat) { int *oformat,len,alen,t,i,j,id; char *p,token[16]; alen=128; oformat=(int *)malloc(sizeof(int)*alen); len=0; while ( *iformat ) { p=iformat;t=0; while ( *p && *p != ',' && t<15 ) { token[t]=*p,p++,t++; }; token[t]=0; while ( *p && *p != ',' ) p++; if ( *p==',' ) p++; iformat=p; if ( len>=alen-16 ) { alen+=128; oformat=(int *)realloc(oformat,sizeof(int)*alen); } for ( i=0,id=-1 ; formatnames[i].id>=0 && id<0 ; i++ ) { for ( j=0 ; formatnames[i].tlist[j] != NULL && id<0 ; j++ ) { if ( strcmp(formatnames[i].tlist[j],token)==0 ) id=formatnames[i].id; } } if ( id<0 ) { free(oformat); return(NULL); } oformat[len]=id; len++; } oformat[len]=-1; return(oformat); } int write_stars(FILE *fw,star *stars,int nstar, int *indx,int is_comment,int *oformat,magflux *mf) { char *opnt,fbuff[16]; star *s; int n,i,j,w,order,ndev,*of,f; int formatlookup[64]; formatname *wf; formatoutparam fop; for ( i=0 ; i<64 ; i++ ) formatlookup[i]=-1; for ( i=0 ; formatnames[i].id>=0 ; i++ ) { j=formatnames[i].id; formatlookup[j]=i; } order=0; for ( j=0 ; jshape.order>order ) order=s->shape.order; } if ( order>0 ) ndev=(order+1)*(order+2)/2-3; else ndev=0; if ( is_comment ) { fprintf(fw,"#"); for ( of=oformat ; *of>=0 ; of++ ) { f=*of; if ( f<0 || f>=64 ) f=-1; else f=formatlookup[f]; if ( f>=0 ) { wf=&formatnames[f]; w=wf->width; opnt=wf->comment; if ( wf->id==I_MOM ) w=8*ndev-1; } else { w=0; opnt=NULL; } if ( opnt != NULL ) { sprintf(fbuff,"%%%ds ",w); fprintf(fw,fbuff,opnt); } } fprintf(fw,"\n"); fprintf(fw,"#"); for ( of=oformat,n=0 ; *of>=0 ; of++,n++ ) { f=*of; if ( f<0 || f>=64 ) f=-1; else f=formatlookup[f]; if ( f>=0 ) { wf=&formatnames[f]; if ( wf->id==I_MOM ) w=wf->width*ndev-1; else w=wf->width; } else w=0; if ( w>0 ) { sprintf(fbuff,"%%%ds[%2d] ",w-4,n+1); fprintf(fw,fbuff,""); } } fprintf(fw,"\n"); } for ( j=0 ; j=0 ; of++ ) { f=*of; if ( f<0 || f>=64 ) f=-1; else f=formatlookup[f]; if ( f>=0 ) wf=&formatnames[f]; else wf=NULL; if ( wf==NULL ) continue; wf->fprint(fw,s,&fop); } fprintf(fw,"\n"); } return(0); } fitsh-0.9.2/src/psf-io.h0000644000175000017500000000304111236250302013400 0ustar apalapal/*****************************************************************************/ /* psf-io.h */ /*****************************************************************************/ #ifndef __PSF_IO_H_INCLUDED #define __PSF_IO_H_INCLUDED 1 #include /* for type (FILE *) */ #include /* for type (fits *) and (fitsimage *) */ #include "psf.h" /* for type (psf *) */ /* psf_write(): Dumps PSF 'p' in a plottable format into the file 'fw'. Plottable means can be plotted with `gnuplot`, with `splot 'psf.dat' u 1:2:3` or like... */ int psf_write(FILE *fw,psf *p); /* psf_write_fits(): Writes PSF 'p' into the file 'fw' in FITS format, as a NAXIS=3 image. The third ('z') axis describes the polynomial variation of the PSF blocks. some extra headers (PSFSGRID, PSFHSIZE, PSFORDER, PSFOFFSX, PSFOFFSY, PSFSCALE) are also written into the FITS image. */ int psf_write_fits(FILE *fw,psf *p); /* psf_parse_fits(): Converts the FITS image 'img' into a PSF (stored in 'p'). The headers written by psf_write_fits() are assumed to exist and have consistent values (e.g. NAXIS1 should be equal to PSFSGRID*(2*PSFHSIZE+1), and like that, see source and the related parts of the documentation. */ int psf_parse_fits(fits *img,psf *p); /* psf_read_fits(): Reads the PSF (which is stored after in 'p') from the stream 'fr'. This function uses psf_parse_fits() and the file should be a consistent PSF file (see constraints above). */ int psf_read_fits(FILE *fr,psf *p); #endif fitsh-0.9.2/src/history.h0000644000175000017500000000113010770004254013706 0ustar apalapal/*****************************************************************************/ /* history.h */ /*****************************************************************************/ #ifndef __HISTORY_H_DEFINED #define __HISTORY_H_DEFINED 1 /*****************************************************************************/ int fits_history_export_command_line(fits *img,char *prg,char *vrs, int argc,char *argv[]); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/magnitude.h0000644000175000017500000000144010667340132014171 0ustar apalapal/*****************************************************************************/ /* magnitude.h */ /*****************************************************************************/ #ifndef __MAGNITUDE_H_INCLUDED #define __MAGNITUDE_H_INCLUDED 1 /*****************************************************************************/ typedef struct { double magnitude; double intensity; } magflux; double mag_to_flux(double magn,magflux *mf); double flux_to_mag(double flux,magflux *mf); int flux_to_mag_magerr(double f,double fe,magflux *mf,double *rm,double *rme); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/kernel-io.c0000644000175000017500000003331012771247725014111 0ustar apalapal/*****************************************************************************/ /* kernel-io.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Base functions for manipulating convolution kernels. */ /*****************************************************************************/ #include #include #include #include #include #include #include "fitsh.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "io/tokenize.h" #include "io/iof.h" #include "tensor.h" #include "kernel.h" /*****************************************************************************/ int dump_kernel(FILE *fw,kernel *k) { fits *img; img=fits_create(); img->i.data=k->image; img->i.sx=img->i.sy=2*k->hsize+1; img->i.bit=-32; fits_set_standard(img,NULL); fits_set_image_params(img); fits_write(fw,img); img->i.data=NULL; img->i.sx=img->i.sy=0; fits_free(img); return(0); } /*****************************************************************************/ int kernel_info_dump_image(FILE *fw,kernel *k,int is_comment) { int i,j,n; n=k->hsize*2+1; for ( i=0 ; iimage[i][j]); if ( inkernel; kernels=kl->kernels; fprintf(fw,"# Kernel set description file (automatically generated by ficonv)\n"); fprintf(fw,"# Do not edit unless you really know what you are doing!!!\n"); fprintf(fw,"\n"); fprintf(fw,"[global]\n"); fprintf(fw,"type = %d\n",kl->type); if ( kl->type==1 ) { fprintf(fw,"offset = %10g, %10g\n",kl->ox,kl->oy); fprintf(fw,"scale = %10g\n",kl->scale); } fprintf(fw,"[end]\n\n"); for ( n=0 ; ntype ) { case KERNEL_UNKNOWN: fprintf(fw,"type = unknown\n"); fprintf(fw,"hsize = %d\n",k->hsize); if ( k->image != NULL ) kernel_info_dump_image(fw,k,0); fprintf(fw,"offset = %10g\n",k->offset); break; case KERNEL_BACKGROUND: fprintf(fw,"type = background\n"); break; case KERNEL_IDENTITY: fprintf(fw,"type = identity\n"); break; case KERNEL_GAUSSIAN: fprintf(fw,"type = gaussian\n"); fprintf(fw,"hsize = %d\n",k->hsize); fprintf(fw,"sigma = %g\n",k->sigma); fprintf(fw,"basis = %d,%d\n",k->bx,k->by); if ( k->image != NULL ) kernel_info_dump_image(fw,k,1); break; case KERNEL_DDELTA: fprintf(fw,"type = ddelta\n"); fprintf(fw,"basis = %d,%d\n",k->bx,k->by); if ( k->image != NULL ) kernel_info_dump_image(fw,k,1); break; } fprintf(fw,"order = %d\n",k->order); nvar=(k->order+1)*(k->order+2)/2; if ( k->coeff != NULL && kl->type==1 ) { fprintf(fw,"coeff ="); for ( i=0 ; icoeff[i]); if ( itype==1 ) /* dump also kernel image */ { hsize=0;order=0; for ( n=0 ; ntype==KERNEL_BACKGROUND && k->coeff != NULL ) { fprintf(fw,"# Background:\n"); nvar=(k->order+1)*(k->order+2)/2; fprintf(fw,"# "); for ( i=0 ; icoeff[i]); } fprintf(fw,"\n"); } else { if ( k->hsize>hsize ) hsize=k->hsize; if ( k->order>order ) order=k->order; } } fsize=2*hsize+1; nvar=(order+1)*(order+2)/2; image=tensor_alloc_3d(double,fsize,fsize,nvar); for ( n=0 ; norder+1)*(k->order+2)/2; if ( k->type == KERNEL_BACKGROUND ) continue; else if ( k->type == KERNEL_IDENTITY ) { for ( i=0 ; icoeff[i]; } } else { for ( i=0 ; ihsize ; p<=k->hsize ; p++ ) { for ( q=-k->hsize ; q<=k->hsize ; q++ ) { image[i][hsize+p][hsize+q]+= k->image[k->hsize+p][k->hsize+q]*k->coeff[i]; } } } } } fprintf(fw,"# Image:\n"); nvar=(order+1)*(order+2)/2; for ( p=-hsize ; p<=hsize ; p++ ) { for ( q=-hsize ; q<=hsize ; q++ ) { fprintf(fw,"# %3d %3d ",q,p); for ( i=0 ; ikernels=kernels=NULL; kl->nkernel=nkernel=0; kl->ox=0.0;kl->oy=0.0; kl->scale=1.0; rbuff=NULL;in_block=0; k=NULL; while ( ! feof(fr) ) { if ( rbuff != NULL ) free(rbuff); rbuff=freadline_bs(fr); if ( rbuff==NULL ) break; remove_spaces_and_comments(rbuff); n=tokenize_char(rbuff,cmd,'=',2); if ( n==0 ) continue; if ( strcmp(cmd[0],"[kernel]")==0 ) { if ( ! in_block ) { in_block=2; kernels=(kernel *)realloc(kernels,sizeof(kernel)*(nkernel+1)); k=&kernels[nkernel]; k->type=-1; k->order=0; k->coeff=NULL; k->hsize=0; } else { free(rbuff);return(1); } } else if ( strcmp(cmd[0],"[global]")==0 ) { if ( ! in_block ) { in_block=1; } else { free(rbuff);return(1); } } else if ( strcmp(cmd[0],"[end]")==0 ) { if ( in_block==1 ) { in_block=0; } else if ( in_block==2 ) { in_block=0; nkernel++; } else { free(rbuff);return(1); } } else if ( ! in_block ) { free(rbuff);return(1); } else if ( cmd[1]==NULL ) { free(rbuff);return(1); } else if ( in_block==1 ) { if ( strcmp(cmd[0],"offset")==0 ) { sscanf(cmd[1],"%lg,%lg",&kl->ox,&kl->oy); } else if ( strcmp(cmd[0],"scale")==0 ) { sscanf(cmd[1],"%lg",&kl->scale); } else if ( strcmp(cmd[0],"type")==0 ) { sscanf(cmd[1],"%d",&kl->type); } else { free(rbuff);return(1); } } else if ( in_block==2 ) { if ( strcmp(cmd[0],"type")==0 ) { if ( k->type >= 0 ) { free(rbuff);return(1); } if ( strcmp(cmd[1],"unknown")==0 ) k->type=KERNEL_UNKNOWN; else if ( strcmp(cmd[1],"background")==0 ) k->type=KERNEL_BACKGROUND; else if ( strcmp(cmd[1],"identity")==0 ) k->type=KERNEL_IDENTITY; else if ( strcmp(cmd[1],"gaussian")==0 ) k->type=KERNEL_GAUSSIAN; else if ( strcmp(cmd[1],"ddelta")==0 ) k->type=KERNEL_DDELTA; else { free(rbuff);return(1); } } else if ( strcmp(cmd[0],"order")==0 ) { sscanf(cmd[1],"%d",&k->order); } else if ( strcmp(cmd[0],"coeff")==0 ) { int i,nvar; char **icmd; nvar=(k->order+1)*(k->order+2)/2; icmd=(char **)malloc(sizeof(char *)*(nvar+1)); k->coeff=(double *)malloc(sizeof(double)*(nvar)); tokenize_char(cmd[1],icmd,',',nvar); for ( i=0 ; icoeff[i])<1 || ! isfinite(k->coeff[i]) ) { free(rbuff);return(1); } } free(icmd); } else if ( strcmp(cmd[0],"hsize")==0 && ( k->type==KERNEL_UNKNOWN || k->type==KERNEL_GAUSSIAN ) ) { sscanf(cmd[1],"%d",&k->hsize); } else if ( strcmp(cmd[0],"basis")==0 && ( k->type==KERNEL_DDELTA || k->type==KERNEL_GAUSSIAN ) ) { sscanf(cmd[1],"%d,%d",&k->bx,&k->by); } else if ( strcmp(cmd[0],"sigma")==0 && ( k->type==KERNEL_GAUSSIAN ) ) { sscanf(cmd[1],"%lg",&k->sigma); } else if ( strcmp(cmd[0],"offset")==0 && ( k->type==KERNEL_UNKNOWN ) ) { sscanf(cmd[1],"%lg",&k->offset); } else if ( strcmp(cmd[0],"image")==0 && ( k->type==KERNEL_UNKNOWN ) ) { int i,n,size; char **icmd; size=2*k->hsize+1; n=size*size; icmd=(char **)malloc(sizeof(char *)*(n+1)); k->image=matrix_alloc(size); tokenize_char(cmd[1],icmd,',',n); for ( i=0 ; iimage[i/size][i%size]); } free(icmd); } else { free(rbuff);return(1); } } } kl->kernels=kernels; kl->nkernel=nkernel; return(0); } /*****************************************************************************/ kernel *add_kernel_empty(kernellist *kl) { kernel *k; if ( kl->nkernel==0 ) kl->kernels=(kernel *)malloc(sizeof(kernel)); else kl->kernels=(kernel *)realloc(kl->kernels,sizeof(kernel)*(kl->nkernel+1)); kl->nkernel++; k=&kl->kernels[kl->nkernel-1]; k->type=-1; k->hsize=0; k->bx=k->by=0; k->sigma=0.0; k->image=NULL; k->order=0; k->coeff=NULL; return(k); } int add_kernel_gaussian(kernellist *kl,double sigma,int hx,int hy,int hsize,int sporder) { kernel *k; k=add_kernel_empty(kl); k->type=KERNEL_GAUSSIAN; k->sigma=sigma; k->bx=hx; k->by=hy; k->hsize=hsize; k->order=sporder; return(0); } int add_kernel_gaussian_set(kernellist *kl,double sigma,int order,int hsize,int sporder) { int i,j; for ( i=0 ; i<=order ; i++ ) { for ( j=0 ; j<=i ; j++ ) { add_kernel_gaussian(kl,sigma,i-j,j,hsize,sporder); } } return(0); } int add_kernel_background(kernellist *kl,int sporder) { kernel *k; k=add_kernel_empty(kl); k->type=KERNEL_BACKGROUND; k->order=sporder; return(0); } int add_kernel_identity(kernellist *kl,int sporder) { kernel *k; k=add_kernel_empty(kl); k->type=KERNEL_IDENTITY; k->order=sporder; return(0); } int add_kernel_linear(kernellist *kl,int px,int py,int sporder) { kernel *k; k=add_kernel_empty(kl); k->type=KERNEL_DDELTA; k->bx=px,k->by=py; k->order=sporder; return(0); } int add_kernel_shift(kernellist *kl,int sporder) { add_kernel_linear(kl,1,0,sporder); add_kernel_linear(kl,0,1,sporder); add_kernel_linear(kl,1,1,sporder); return(0); } int add_kernel_linear_set(kernellist *kl,int ksize,int sporder) { int i; for ( i=-ksize ; i<=ksize ; i++ ) { add_kernel_linear(kl,i,-ksize,sporder); add_kernel_linear(kl,i,+ksize,sporder); } for ( i=-ksize+1 ; i<=ksize-1 ; i++ ) { add_kernel_linear(kl,-ksize,i,sporder); add_kernel_linear(kl,+ksize,i,sporder); } return(0); } int kernel_init_images(kernellist *kl) { int i,fnn,fnt; kernel *k; for ( i=0 ; inkernel ; i++ ) { k=&kl->kernels[i]; if ( k->type==KERNEL_GAUSSIAN ) { kernel_image_calc_gaussian(k); } if ( k->type==KERNEL_DDELTA ) { kernel_image_calc_linear(k); } } fnn=-1,fnt=0; for ( i=0 ; inkernel && fnn<0 ; i++ ) { k=&kl->kernels[i]; if ( k->type==KERNEL_IDENTITY ) fnn=i,fnt=KERNEL_IDENTITY; if ( k->type==KERNEL_GAUSSIAN && k->bx%2==0 && k->by%2==0 ) fnn=i,fnt=KERNEL_GAUSSIAN; } if ( fnn>=0 && fnt==KERNEL_IDENTITY ) { for ( i=fnn+1 ; inkernel ; i++ ) { k=&kl->kernels[i]; if ( k->type==KERNEL_GAUSSIAN && k->bx%2==0 && k->by%2==0 ) k->image[k->hsize][k->hsize]-=1.0; } } else if ( fnn>=0 && fnt==KERNEL_GAUSSIAN ) { for ( i=fnn+1 ; inkernel ; i++ ) { k=&kl->kernels[i]; if ( k->type==KERNEL_GAUSSIAN && k->bx%2==0 && k->by%2==0 ) kernel_image_subtract(k,&kl->kernels[fnn]); } } return(0); } int create_kernels_from_kernelarg(char *kernelarg,kernellist *kl) { char *karg,*cmd[32],*icmd[4],*jcmd[4]; int is_bg,is_id,is_g,is_d,is_s,i,j,linear_set_added; kl->nkernel=0; kl->kernels=NULL; kl->ox=kl->oy=0.0; kl->scale=1.0; kl->type=0; karg=(char *)malloc(strlen(kernelarg)+1); strcpy(karg,kernelarg); remove_spaces_and_comments(karg); is_bg=is_id=is_g=is_d=is_s=-1; tokenize_char(karg,cmd,';',31); for ( i=0 ; cmd[i] != NULL ; i++ ) { if ( cmd[i][0]=='i' ) is_id=i; else if ( cmd[i][0]=='b' ) is_bg=i; else if ( cmd[i][0]=='g' ) is_g=i; else if ( cmd[i][0]=='d' ) is_d=i; else if ( cmd[i][0]=='s' ) is_s=i; else { free(karg);return(1); } } if ( is_bg>=0 ) { int sporder; tokenize_char(cmd[is_bg],jcmd,'/',2); sporder=-1; if ( jcmd[1] != NULL ) { sscanf(jcmd[1],"%d",&sporder); } else sporder=0; if ( sporder<0 ) { free(karg);return(1); } add_kernel_background(kl,sporder); } if ( is_id>=0 ) { int sporder; tokenize_char(cmd[is_id],jcmd,'/',2); sporder=-1; if ( jcmd[1] != NULL ) { sscanf(jcmd[1],"%d",&sporder); } else sporder=0; if ( sporder<0 ) { free(karg);return(1); } add_kernel_identity(kl,sporder); } if ( is_s>=0 ) { int sporder; tokenize_char(cmd[is_s],jcmd,'/',2); sporder=-1; if ( jcmd[1] != NULL ) { sscanf(jcmd[1],"%d",&sporder); } else sporder=0; if ( sporder<0 ) { free(karg);return(1); } add_kernel_shift(kl,sporder); } for ( i=0 ; cmd[i] != NULL ; i++ ) { double sigma; int hsize,order; int sporder; if ( cmd[i][0] != 'g' ) continue; tokenize_char(cmd[i],icmd,'=',2); if ( icmd[1]==NULL ) { free(karg);return(1); } sporder=0; if ( sscanf(icmd[1],"%d,%lg,%d/%d",&hsize,&sigma,&order,&sporder)<3 ) { free(karg);return(1); } if ( sporder<0 ) { free(karg);return(1); } add_kernel_gaussian_set(kl,sigma,order,hsize,sporder); } linear_set_added=0; for ( i=0 ; cmd[i] != NULL ; i++ ) { int hsize; int sporder; if ( cmd[i][0] != 'd' ) continue; tokenize_char(cmd[i],icmd,'=',2); if ( icmd[1]==NULL ) { free(karg);return(1); } sporder=0; if ( sscanf(icmd[1],"%d/%d",&hsize,&sporder)<1 ) { free(karg);return(1); } if ( sporder<0 ) { free(karg);return(1); } for ( j=linear_set_added+1 ; j<=hsize ; j++ ) { add_kernel_linear_set(kl,j,sporder); } linear_set_added=hsize; } free(karg); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/wcs.c0000644000175000017500000000644212463220125013005 0ustar apalapal/*****************************************************************************/ /* wcs.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Some functions related to sky coordinate conversions & projections */ /*****************************************************************************/ #include #include #include #include #include "wcs.h" /*****************************************************************************/ int wcs_get_projection_matrix(double ra0,double de0,matrix mproj) { double sr0,sd0,cr0,cd0; ra0=M_D2R*ra0; de0=M_D2R*de0; sr0=sin(ra0); cr0=cos(ra0); sd0=sin(de0); cd0=cos(de0); mproj[0][0]=+sr0 ,mproj[0][1]=-cr0 ,mproj[0][2]=0.0; mproj[1][0]=-sd0*cr0,mproj[1][1]=-sd0*sr0,mproj[1][2]=+cd0; mproj[2][0]=-cd0*cr0,mproj[2][1]=-cd0*sr0,mproj[2][2]=-sd0; return(0); } int wcs_get_projected_coords_matrix(matrix mproj,double ra,double de,double *rx,double *ry,double *rz) { double sr,sd,cr,cd,x,y,z; ra=M_D2R*ra; de=M_D2R*de; sr=sin(ra); cr=cos(ra); sd=sin(de); cd=cos(de); x=cd*cr; y=cd*sr; z=sd; *rx=mproj[0][0]*x+mproj[0][1]*y+mproj[0][2]*z; *ry=mproj[1][0]*x+mproj[1][1]*y+mproj[1][2]*z; *rz=mproj[2][0]*x+mproj[2][1]*y+mproj[2][2]*z; return(0); } int wcs_invert_projected_coords_matrix(matrix mproj,double x,double y,double *rra,double *rde) { double z,px,py,pz; z=1.0-x*x-y*y; if ( z<0.0 ) return(1); else z=-sqrt(z); px=mproj[0][0]*x+mproj[1][0]*y+mproj[2][0]*z; py=mproj[0][1]*x+mproj[1][1]*y+mproj[2][1]*z; pz=mproj[0][2]*x+mproj[1][2]*y+mproj[2][2]*z; *rde=asin(pz)*M_R2D; *rra=atan2(py,px)*M_R2D; if ( *rra<0.0 ) *rra+=360.0; return(0); } int wcs_project_distort(int type,double *rx,double *ry,double *rz) { double d,m; switch ( type ) { case WCS_TAN: /* gnomonic projection */ m=1.0/sqrt(1-(*rx)*(*rx)-(*ry)*(*ry)); *rx=(*rx)*m; *ry=(*ry)*m; break; case WCS_ARC: /* arc projection */ d=sqrt((*rx)*(*rx)+(*ry)*(*ry)); if ( d>0.0 && *rz < 0.0 ) m=asin(d)/d; else if ( d>0.0 ) m=(M_PI-asin(d))/d; else m=1.0; *rx=(*rx)*m; *ry=(*ry)*m; break; case WCS_SIN: /* orthographic: do nothing, successfully */ break; default: /* unknown projection */ return(1); break; } return(0); } int wcs_invert_project_distort(int type,double *rx,double *ry,double *rz) { double d,m; switch ( type ) { case WCS_TAN: /* gnomonic projection */ m=1.0/sqrt(1+(*rx)*(*rx)+(*ry)*(*ry)); *rx=(*rx)*m; *ry=(*ry)*m; break; case WCS_ARC: /* arc projection */ d=sqrt((*rx)*(*rx)+(*ry)*(*ry)); if ( d>0.0 ) m=sin(d)/d; else m=1.0; *rx=(*rx)*m; *ry=(*ry)*m; break; case WCS_SIN: /* orthographic: do nothing, successfully */ break; default: /* unknown projection */ return(1); break; } return(0); } int wcs_get_projected_coords(double ra,double de,double ra0,double de0,double *rx,double *ry,double *rz) { double sinda,cosda,sind0,sind,cosd0,cosd; ra =M_D2R*(ra-ra0); de0=M_D2R*de0; de =M_D2R*de; sinda=sin(ra); cosda=cos(ra); sind0=sin(de0); cosd0=cos(de0); sind =sin(de); cosd =cos(de); *rx=+cosd*sinda; *ry=-sind0*cosd*cosda+cosd0*sind; *rz=+cosd0*cosd*cosda+sind0*sind; return(0); } /*****************************************************************************/ fitsh-0.9.2/src/fiign.c0000644000175000017500000004276212771247727013335 0ustar apalapal/*****************************************************************************/ /* fiign.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line user interface for ignorig false pixels from a (FITS) image. */ /*****************************************************************************/ #define FITSH_FIIGN_VERSION "0.9e" /*****************************************************************************/ #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "fitsmask.h" #include "math/poly.h" #include "statistics.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "maskdraw.h" #include "tensor.h" #include "common.h" #include "history.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ int is_verbose,is_comment; /*****************************************************************************/ typedef struct { int match; int value; int reset; int set; } maskconvert; typedef struct { int x0,y0; int sx,sy; int mask; } maskblock; /*****************************************************************************/ char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int ignore_cosmics(fitsimage *img,char **mask,double th_low,double th_high,int is_repl,double skysigma) { int i,j,k,l,hsize,fsize,ii,jj; int sx,sy; double arr[25],s,s2,sig,w; int is_low,is_high; if ( img==NULL ) return(1); if ( img->data==NULL ) return(0); sx=img->sx,sy=img->sy; is_low=is_high=0; if ( th_low > 0.0 ) is_low =1; if ( th_high > 0.0 ) is_high=1; hsize=1; fsize=2*hsize+1; for ( i=hsize ; idata[i+ii][j+jj]; arr[l]=w;l++; } if ( jj==hsize ) ii++,jj=-hsize; else jj++; } if ( l0.0 && sig>2*skysigma ) continue; if ( skysigma>0.0 ) sig=skysigma; if ( is_low && img->data[i][j] < s - th_low *sig ) { mask[i][j] |= MASK_COSMIC; if ( is_repl ) { img->data[i][j]=s, mask[i][j] |= MASK_INTERPOLATED; } } if ( is_high && img->data[i][j] > s + th_high*sig ) { mask[i][j] |= MASK_COSMIC; if ( is_repl ) { img->data[i][j]=s, mask[i][j] |= MASK_INTERPOLATED; } } } } return(0); } /* int ignore_cosmics_biquad(fits *img,char **mask) { int sx,sy,i,j,k,l,subg,n,mi,mj; double **bqc,**subc,mmin,nbmax,nbmin,pval,w,s,s2; if ( mask==NULL ) return(1); if ( img==NULL ) return(1); if ( img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); subg=4; bqc=tensor_alloc_2d(double,2*sx+1,2*sy+1); if ( bqc==NULL ) return(-1); subc=tensor_alloc_2d(double,subg,subg); if ( subc==NULL ) return(-1); for ( i=0 ; idata,sx,sy,bqc,mask); for ( i=0 ; idata[i][j]; n=0;s=s2=nbmax=nbmin=0.0;mi=mj=0; if ( j>0 && mask[i][j-1] ) { w=img->data[i][j-1]; if ( n==0 || w>nbmax ) nbmax=w,mi=i,mj=j-1; if ( n==0 || wdata[i][j+1]; if ( n==0 || w>nbmax ) nbmax=w,mi=i,mj=j+1; if ( n==0 || w0 && mask[i-1][j] ) { w=img->data[i-1][j]; if ( n==0 || w>nbmax ) nbmax=w,mi=i-1,mj=j; if ( n==0 || wdata[i+1][j]; if ( n==0 || w>nbmax ) nbmax=w,mi=i+1,mj=j; if ( n==0 || w=2 && mminpval ) { s-=nbmax,s2-=nbmax*nbmax; s/=(double)(n-1),s2/=(double)(n-1); s2=sqrt(s2-s*s); if ( 3.0*(nbmin-mmin)<(nbmax-pval) && 100.0*s2[] [--frame ]] [-o|--output ]\n" "\t[-V|--verbose] [-C|--comment]\n"); fprintf(fw, "General options:\n" "\t[--ignore-mask | -M|--input-mask ]\n" "\t[-a|--apply-mask [-m|--mask-value ]] [--output-mask ]\n"); fprintf(fw, "Mask conversion:\n" "\t[--convert ::: [--convert <>:<>:<>:<>] ...]\n"); fprintf(fw, "Marking saturated pixels:\n" "\t[-s |-S ]\n" "\t[--leak-{left-right|lower-upper|any}|--lr|--lu|--an]\n"); fprintf(fw, "General ignorance:\n" "\t[-n|--ignore-nonpositive] [-g|--ignore-negative] [-z|--ignore-zero]\n"); fprintf(fw, "Cosmics removal and/or interpolation:\n" "\t[-c|--ignore-cosmics [-r|--replace-cosmics]]\n"); return(0); } longhelp_entry fiign_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-i, --input ", "Name of the input FITS image file." }, { "-o, --output ", "Name of the output FITS image file (can be the same as the input " "image file)." }, { "Generic pixel masking options:", NULL }, { "-n, --ignore-nonpositive", "Mask pixels with non-positive values." }, { "-g, --ignore-negative", "Mask pixels with negative values." }, { "-z, --ignore-zero", "Mask pixels with a value of zero." }, { "--ignore-mask", "Completely ignore mask associated to the input image." }, { "-M, --input-mask ", "Input mask file to co-add to output image mask." }, { "-a, --apply-mask", "Apply the mask to the image, i.e. set the pixel values with non-null " "mask to be zero (by default, or any other value specified by " "\"-m|--mask-value\")." }, { "-m, --mask-value ", "Override the default pixel value (zero) during explicit marking of " "masked pixels (see also \"-a|--apply-mask\")." }, { "Marking saturated pixels:", NULL }, { "-s ", "Saturation level." }, { "-S ", "Image containing saturation level on a per pixel basis." }, { "--leak-left-right, --leak-lower-upper, --leak-any", "Readout direction, i.e. orientation of \"blooming\" stripes." }, { "Mask conversion:", NULL }, { "--convert :::", "Convert masks: from a mask which matches to the : pair, " "i.e. the masks with the type of have a value of " "the masks specified by are cleared and the masks specified by " " are set. The , , and tags are " "comma-separated list of mask names (see below)." }, { "Mask names:", NULL }, { "none", "no mask at all" }, { "clear", "same as \"none\"" }, { "fault", "mask for faulty pixels" }, { "hot", "mask for hot pixels" }, { "cosmic", "mask for marking cosmic pixels" }, { "outer", "pixels originating from out of image areas" }, { "oversaturated", "oversaturated pixels" }, { "bloomed", "\"bloomed\" pixels (i.e. not oversaturated but neighbouring pixel(s) may be so)" }, { "saturated", "oversaturated or bloomed pixels" }, { "interpolated", "pixels having an interpolated value (e.g. hot or cosmic pixels are " "replaced by the average value of the surrounding pixels)." }, { NULL, NULL } }; int fprint_fiign_long_help(FILE *fw,int is_wiki) { char *synopsis= "fiign [options and operations] [] [-o|--output ]"; char *description= __extension__ "In the context of FITS image data processing, \"masks\" are per pixel " "associated meta-data, representing the state of the given pixel. In " "general, pixels considered to be somehow \"bad\" are marked with these masks " "in order to exclude or use only with caution during further processing. " "These masks can either mark the initial state of the given pixels (e.g. " "pixels can be marked as hot or bad pixels, which describes the detector itself " "and not the individual scientific or calibration frames), or masks can be " "added during the subsequent steps of the processing (e.g. saturated pixels, " "\"outer\" pixels). " "The purpose of the `fiign` program is to give a low-level " "access to these masks. Although the operations on the images automatically " "yields the respective operations on the masks (e.g. if an image is transformed " "or trimmed, the associated mask will also be transformed or trimmed " "with the same geometry), with this program the masks can be manipulated " "arbitrarily."; fprint_generic_long_help(fw,is_wiki,fiign_long_help,synopsis,description); return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { fits *img,*satimg; char **mask; FILE *fw,*ft,*fr; int i,j,sx,sy,is_help,is_no_mask; double saturation,skysigma,threshold,thlow,thhigh,maskvalue; char *satimgname,*inimgname,*outimgname,*outmaskname,**inmasklist, *ignmasknames,**convertlist,*basename,**maskblocklist; int ign_cosmics,rep_cosmics,ign_num,frameno, reset_method,apply_mask; maskconvert *mcls; int nmcl; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; saturation=0.0;threshold=4.0;skysigma=0.0; thlow=10.0;thhigh=50.0; is_no_mask=is_verbose=is_comment=is_help=0; reset_method=0;apply_mask=0;ign_num=0;ign_cosmics=rep_cosmics=0; inimgname=outimgname=outmaskname=satimgname=NULL;frameno=0; ignmasknames=NULL;inmasklist=convertlist=NULL;maskvalue=0.0; maskblocklist=NULL; mcls=NULL;nmcl=0; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-i|--input:%s",&inimgname, "-q|--mask-block:%Dt",&maskblocklist, "--frame:%d",&frameno, "-o|--output:%s",&outimgname, "--output-mask:%s",&outmaskname, "-M|--input-mask:%t",&inmasklist, "-d:%g",&skysigma, "-t|--threshold:%g",&threshold, "--threshold-low:%g",&thlow, "--threshold-high:%g",&thhigh, "-c|--ignore-cosmics:%f",&ign_cosmics, "-r|--replace-cosmics:%f%f",&ign_cosmics,&rep_cosmics, "-z|--ignore-zero:%N1f",&ign_num, "-g|--ignore-negative:%N2f",&ign_num, "-n|--ignore-nonpositive:%N3f",&ign_num, "-a|--apply-mask:%f",&apply_mask, "-m|--mask-value:%g",&maskvalue, "--no-mask|--ignore-mask:%f",&is_no_mask, "--mask-ignore:%s",&ignmasknames, "--convert:%t",&convertlist, "--lu:%N1f",&reset_method, "--lr:%N2f",&reset_method, "--an:%N3f",&reset_method, "-s|--saturation:%g",&saturation, "-S|--saturation-image:%s",&satimgname, "--comment:%i",&is_comment,"(C):%i",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-:%w",&inimgname, "-*|+*:%e", "*:%w",&inimgname, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fiign",FITSH_FIIGN_VERSION,is_help); return(0); } else if ( 1match=k; wm->value=k; wm->reset=reset; wm->set=set; nmcl++; } } else { mcls=(maskconvert *)realloc(mcls,sizeof(maskconvert)*(nmcl+1)); wm=&mcls[nmcl]; wm->match=match; wm->value=value; wm->reset=reset; wm->set=set; nmcl++; } } } basename=fits_basename(inimgname,&frameno); if ( (fr=fopenread(basename))==NULL ) { fprint_error("unable to open input file '%s'.",basename); return(1); } img=fits_read_frame_to_image(fr,frameno); fclose(fr); if ( img==NULL ) { fprint_error("unable to interpret input as FITS data."); return(1); } if ( img->i.dim != 2 ) { fprint_error("image dimension differs from 2."); return(1); } fits_rescale(img); sx=img->i.sx, sy=img->i.sy; if ( is_no_mask ) mask=fits_mask_create_empty(sx,sy); else mask=fits_mask_read_from_header(&img->header,sx,sy,NULL); if ( inmasklist != NULL ) { if ( join_masks_from_files(mask,sx,sy,inmasklist) ) { fprint_error("unable to read one of the input mask files"); return(1); } } fits_mask_mark_nans(&img->i,mask,MASK_NAN); if ( ignmasknames != NULL ) { int flag; flag=parse_mask_flags(ignmasknames); if ( flag<0 ) { fprint_error("invalid mask specification '%s'",ignmasknames); return(1); } for ( i=0 ; ii.dim != 2 ) { fprint_error("saturation image is not 2D"); return(1); } fcloseread(ft); if ( sx != satimg->i.sx || sy != satimg->i.sy ) { fprint_error("input and saturation image size differ"); return(1); } } else satimg=NULL; if ( satimg != NULL ) mark_saturated_pixels(&img->i,mask,&satimg->i,1.0,reset_method); else if ( saturation > 0.0 ) mark_saturated_pixels(&img->i,mask,NULL,saturation,reset_method); for ( i=0 ; maskblocklist != NULL && maskblocklist[i] != NULL ; i++ ) { if ( maskdraw_parse_and_draw(mask,sx,sy,maskblocklist[i])>0 ) { fprint_warning("invalid mask block specification '%s', skipped.\n",maskblocklist[i]); } } if ( ign_num ) { int cm; for ( i=0 ; ii.data[i][j]==0.0 ) cm=1; else if ( img->i.data[i][j]< 0.0 ) cm=2; else cm=0; if ( cm & ign_num ) mask[i][j] |= MASK_FAULT; } } } if ( ign_cosmics ) ignore_cosmics(&img->i,mask,thlow,thhigh,rep_cosmics,skysigma); for ( i=0 ; imatch)==(wm->value & wm->match) ) mask[i][j]=(m&(~wm->reset))|wm->set; } } } if ( apply_mask ) { for ( i=0 ; ii.data[i][j]=maskvalue; } } } fits_history_export_command_line(img,"fiign",FITSH_FIIGN_VERSION,argc,argv); fits_set_image_params(img); fits_backscale(img,img->i.read.bscale,img->i.read.bzero); mark_integerlimited_pixels(&img->i,mask,img->i.bit,1,MASK_OVERSATURATED,MASK_OVERSATURATED); fits_mask_export_as_header(&img->header,1,mask,sx,sy,NULL); if ( outimgname==NULL ) fw=stdout; else fw=fopenwrite(outimgname); if ( fw==NULL ) { fprint_error("unable to create output image file '%s'",outimgname); return(1); } fits_write(fw,img); fclosewrite(fw); if ( outmaskname != NULL ) { fw=fopenwrite(outmaskname); if ( fw==NULL ) { fprint_error("unable to create output mask file '%s'",outmaskname); return(1); } fits_write_header(fw,img); fclosewrite(fw); } fits_free(img); if ( satimg != NULL ) fits_free(satimg); fits_mask_free(mask); return(0); } fitsh-0.9.2/src/xfunct.c0000644000175000017500000000372011236270457013526 0ustar apalapal/*****************************************************************************/ /* xfunct.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Some extra functions for extending the default 'lfit' functionality: */ /* - eccentric_offset_{q,p}(l,k,h) -- eop(), eoq(): eccentric offset */ /* functions and their derivatives (these functions are analytic for */ /* k^2 + h^2 < 1 and for all values of l). */ /* - HJD and BJD functions */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2007; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include "xfunct.h" /*****************************************************************************/ double eccentric_offset_q(double lambda,double k,double h) { double e,E; e=sqrt(h*h+k*k); if ( e<=0.0 ) return(0.0); else { E=solve_kepler_equ(lambda-atan2(h,k),e); return(e*cos(E)); } } double eccentric_offset_p(double lambda,double k,double h) { double e,E; e=sqrt(h*h+k*k); if ( e<=0.0 ) return(0.0); else { E=solve_kepler_equ(lambda-atan2(h,k),e); return(e*sin(E)); } } double eccentric_trigonometric_c(double lambda,double k,double h) { return(cos(lambda+eccentric_offset_p(lambda,k,h))); } double eccentric_trigonometric_s(double lambda,double k,double h) { return(sin(lambda+eccentric_offset_p(lambda,k,h))); } /*****************************************************************************/ double get_hjd(double jd,double ra,double dec) { double hjd; hjd=get_heliocentric_julian_date(jd,ra,dec); return(hjd); } double get_bjd(double jd,double ra,double dec) { double bjd; bjd=get_barycentric_julian_date(jd,ra,dec); return(bjd); } /*****************************************************************************/ fitsh-0.9.2/src/longhelp.h0000644000175000017500000000567012766034436014046 0ustar apalapal/*****************************************************************************/ /* longhelp.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Copyright (C) 2008; Pal, A. (apal@szofi.elte.hu) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions for creating nice ``long helps'' */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This library 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 the program. If not, see . */ /*****************************************************************************/ #ifndef __LONGHELP_H_INCLUDED #define __LONGHELP_H_INCLUDED 1 /*****************************************************************************/ /* these are specific terms which are supported by the ``help2man'' utility. */ #define LONGHELP_OPTIONS { "Options:", NULL } #define LONGHELP_EXAMPLES { "Examples:", NULL } /*****************************************************************************/ typedef struct { char *options; char *description; } longhelp_entry; /*****************************************************************************/ /* longhelp_fprint(): Prints the (NULL,NULL)-terminated longhelp_entry array `entries` to the file stream referred by `fw`. The output is formatted for `width` width, if it is positive, ignored at all if `width` is zero and calculated automatically if it is negative (in this case, if `fw` refers to a terminal, the width is derived automatically from the terminal window size argument, otherwise the formatting is ignored). */ int longhelp_fprint(FILE *fw,longhelp_entry *entries,int flags,int width); /* longhelp_fprint_mediawiki(): Prints the (NULL,NULL)-terminated longhelp_entry array `entries` to the file stream referred by `fw`, according to the formatting rules and markup used by MediaWiki. The output can then be copy-pasted to a Mediawiki edit form in order to provide a nice manual page in Mediawiki format. */ int longhelp_fprint_mediawiki(FILE *fw,longhelp_entry *entry); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/xfunct.h0000644000175000017500000000310011101733221013503 0ustar apalapal/*****************************************************************************/ /* xfunct.h */ /*****************************************************************************/ #ifndef __XFUNCT_H_INCLUDED #define __XFUNCT_H_INCLUDED 1 /*****************************************************************************/ /* eccentric_offset_q(), eccentric_offset_p(): These functions calculate the components of the eccentric offset vector. The eccentric offset vector (q,p) is e*(cos E,sin E) where e^2 = k^2 + h^2 and E is the solution of E - e*sin E = lambda-arg(k,h). */ double eccentric_offset_q(double lambda,double k,double h); double eccentric_offset_p(double lambda,double k,double h); double eccentric_trigonometric_c(double lambda,double k,double h); double eccentric_trigonometric_s(double lambda,double k,double h); /*****************************************************************************/ double elliptic_complete_first(double k); double elliptic_complete_second(double k); double elliptic_complete_third(double n,double k); /*****************************************************************************/ /* wrapper to get_heiocentric_julian_date(): */ double get_hjd(double jd,double ra,double dec); /* wrapper to get_barycentric_julian_date(): */ double get_bjd(double jd,double ra,double dec); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/background.c0000644000175000017500000000367511236250710014335 0ustar apalapal/*****************************************************************************/ /* background.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to background determination... */ /*****************************************************************************/ #include #include #include #include #include #include "fitsmask.h" #include "math/fit/lmfit.h" #include "statistics.h" #include "math/poly.h" #include "math/polyfit.h" #include "tensor.h" #include "background.h" /*****************************************************************************/ int determine_background(fitsimage *img,spatial *bg,int gx,int gy,int order) { int i,j,sx,sy,nvar; point *dp; if ( img==NULL ) return(1); if ( img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( gx<=0 || gy<=0 ) gx=gy=order+1; nvar=(order+1)*(order+2)/2; bg->order=order; bg->ox=0.5*(double)sx, bg->oy=0.5*(double)sy, bg->scale=0.5*(double)sx; bg->coeff=(double *)malloc(sizeof(double)*nvar); dp=(point *)malloc(sizeof(point)*gx*gy); for ( i=0 ; idata[ii][jj]>0.0 ) rawdata[n]=img->data[ii][jj],n++; } } med=median(rawdata,n); free(rawdata); k=i*gx+j; dp[k].x=(double)(jmax+jmin-1)*0.5; dp[k].y=(double)(imax+imin-1)*0.5; dp[k].value=med; dp[k].weight=1.0; } } fit_2d_poly(dp,gx*gy,order,bg->coeff,bg->ox,bg->oy,bg->scale); free(dp); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/star-cand-trb.c0000644000175000017500000001502212771510546014657 0ustar apalapal/*****************************************************************************/ /* star-cand-trb.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Star candidate searching based on the triangulation algorithm... */ /*****************************************************************************/ #include #include #include #include #include #include "io/iof.h" #include "fitsmask.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/point.h" #include "math/tpoint.h" #include "math/delaunay.h" #include "statistics.h" #include "fitsh.h" #include "common.h" #include "stars.h" #define FLAG_MIN 1 #define FLAG_MAX 2 /*****************************************************************************/ int is_in_triangle(int x1,int y1,int x2,int y2,int x3,int y3,int x,int y) { int a,b,c; a=(x2-x1)*(y-y1)-(x-x1)*(y2-y1); b=(x3-x2)*(y-y2)-(x-x2)*(y3-y2); c=(x1-x3)*(y-y3)-(x-x3)*(y1-y3); if ( (a>=0 && b>=0 && c>=0) || (a<=0 && b<=0 && c<=0) ) return(1); else return(0); } static int is_neighbour(tpoint *p1,tpoint *p2,tpoint *points,tpoint ***allneig) { tpoint **cn; int i; cn=allneig[p2-points]; for ( i=0 ; cn[i] != NULL ; i++ ) { if ( cn[i] == p1 ) return(1); } return(0); } static int order_point_neighbours(tpoint *ps,tpoint *p,tpoint **neig,tpoint ***allneig) { tpoint *cp,*w; int i,j; for ( i=0 ; neig[i+1] != NULL && neig[i] != NULL ; i++ ) { cp=neig[i]; for ( j=i+1 ; neig[j] != NULL ; j++ ) { if ( is_neighbour(cp,neig[j],ps,allneig) ) break; } if ( neig[j]==NULL ) return(1); else if ( neig[j] != NULL && j>i+1 ) w=neig[i+1],neig[i+1]=neig[j],neig[j]=w; } if ( ! is_neighbour(neig[0],neig[i],ps,allneig) ) return(1); else return(0); } /*****************************************************************************/ /* debug stuff */ /* { FILE *fw; tpoint *p1,*p2,*p3; fw=stdout; for ( i=0 ; ixcoord,p1->ycoord,p2->xcoord-p1->xcoord,p2->ycoord-p1->ycoord); fprintf(fw,"%4g %4g %4g %4g\n",p2->xcoord,p2->ycoord,p3->xcoord-p2->xcoord,p3->ycoord-p2->ycoord); fprintf(fw,"%4g %4g %4g %4g\n",p3->xcoord,p3->ycoord,p1->xcoord-p3->xcoord,p1->ycoord-p3->ycoord); } } */ /* i=0; for ( j=0 ; ti.neigs[i][j] != NULL ; j++ ) { fprintf(stderr,"%g %g\n",ti.neigs[i][j]->xcoord,ti.neigs[i][j]->ycoord); } */ /* for ( i=0 ; ixcoord*ti.neigs[i][k]->ycoord; area-=ti.neigs[i][k]->xcoord*ti.neigs[i][j]->ycoord; } fprintf(stderr,"%d %d : %g\n",cands[i].ix,cands[i].iy,area); } */ /*****************************************************************************/ int search_star_candidates_trb(fitsimage *img,char **mask,candidate **rcands,int *rncand,range *srcrange,double treshold) { candidate *cands,*wc,*nc,*nc1,*nc2; int ncand; int c,i,j,k,l,n,sx,sy,imin,imax,jmin,jmax; int ismin,ismax; double w,w0,area,*darr,med,sig,peak; tpoint *tps,**neig; triinfo ti; triangle *tris; int ntri; sx=img->sx,sy=img->sy; ncand=0;cands=NULL; if ( srcrange==NULL ) { imin=0,imax=sy-1, jmin=0,jmax=sx-1; } else { imin=srcrange->ymin,imax=srcrange->ymax; jmin=srcrange->xmin,jmax=srcrange->xmax; if ( imin>imax ) i=imin,imin=imax,imax=i; if ( jmin>jmax ) j=jmin,jmin=jmax,jmax=j; } if ( imin<0 ) imin=0; if ( imax>=sy ) imax=sy-1; if ( jmin<0 ) jmin=0; if ( jmax>=sx ) jmax=sx-1; for ( i=imin ; i<=imax ; i++ ) { for ( j=jmin ; j<=jmax ; j++ ) { if ( mask != NULL && mask[i][j] ) continue; w0=img->data[i][j]; ismin=ismax=1;n=0; for ( k=-1 ; k<=1 ; k++ ) { if ( i+k<0 || i+k>=sy ) continue; for ( l=-1 ; l<=1 ; l++ ) { if ( j+l<0 || j+l>=sx ) continue; if ( mask[i+k][j+l] ) continue; w=img->data[i+k][j+l]; if ( w>w0 ) ismax=0; else if ( wflags=0; if ( ismin ) wc->flags |= FLAG_MIN; if ( ismax ) wc->flags |= FLAG_MAX; wc->ix=j,wc->cx=(double)j+0.5; wc->iy=i,wc->cy=(double)i+0.5; wc->peak=0.0; wc->sxx=0.0; wc->sxy=0.0; wc->syy=0.0; wc->marked=0; wc->ipoints=NULL; wc->nipoint=0; ncand++; } } tps=(tpoint *)malloc(sizeof(tpoint)*ncand); for ( i=0 ; iflags&(FLAG_MAX|FLAG_MIN)) != FLAG_MAX ) { wc->marked=1; continue; } for ( n=0 ; neig[n] != NULL ; ) n++; area=0.0; darr=(double *)malloc(sizeof(double)*n); for ( k=0 ; kxcoord*neig[l]->ycoord; area-=neig[l]->xcoord*neig[k]->ycoord; nc=cands+(neig[k]-tps); darr[k]=img->data[nc->iy][nc->ix]; } med=median(darr,n); for ( k=0 ; kdata[wc->iy][wc->ix]-med; if ( peak > 5 * sig && peak > treshold ) { int xmax,xmin,ymax,ymin,x,y; wc->ipoints=NULL; wc->nipoint=0; xmax=xmin=0; ymax=ymin=0; for ( k=0 ; kix; ymax=ymin=nc->iy; } else { if ( nc->ix > xmax ) xmax=nc->ix; if ( nc->ix < xmin ) xmin=nc->ix; if ( nc->iy > ymax ) ymax=nc->iy; if ( nc->iy < ymin ) ymin=nc->iy; } } wc->ipoints=NULL; wc->nipoint=0; for ( y=ymin ; y<=ymax ; y++ ) { for ( x=xmin ; x<=xmax ; x++ ) { for ( k=0 ; kix,wc->iy,nc1->ix,nc1->iy,nc2->ix,nc2->iy,x,y) ) break; } if ( k==n ) continue; wc->ipoints=(ipoint *)realloc(wc->ipoints,sizeof(ipoint)*(wc->nipoint+1)); wc->ipoints[wc->nipoint].x=x; wc->ipoints[wc->nipoint].y=y; wc->nipoint++; } } wc->marked=0; } else { wc->ipoints=NULL; wc->nipoint=0; wc->marked=1; } wc->area=(double)wc->nipoint; wc->noise=0.0; free(darr); } free(ti.neigs); free(ti.neigpoints); cleanup_candlist(&cands,&ncand); if ( rcands != NULL ) *rcands=cands; if ( rncand != NULL ) *rncand=ncand; return(0); } fitsh-0.9.2/src/common.c0000644000175000017500000000762012771247734013521 0ustar apalapal/*****************************************************************************/ /* common.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Some common stuff for the 'fi' package. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2004-2008; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include "fitsmask.h" #include "math/fit/lmfit.h" #include "math/spline/spline.h" #include "statistics.h" #include "math/poly.h" #include "math/polyfit.h" #include "io/tokenize.h" #include "io/iof.h" #include "tensor.h" #include "fitsh.h" #include "common.h" /*****************************************************************************/ int mark_saturated_pixels(fitsimage *img,char **mask,fitsimage *satimg,double param,int method) { int i,j,sx,sy,c; if ( mask==NULL ) return(-1); sx=img->sx, sy=img->sy; if ( satimg != NULL ) { if ( sx != satimg->sx || sy != satimg->sy ) return(1); for ( i=0 ; idata[i][j]>=satimg->data[i][j]*param ) mask[i][j] |= MASK_OVERSATURATED; } } } else { for ( i=0 ; idata[i][j]>=param ) mask[i][j] |= MASK_OVERSATURATED; } } } for ( i=0 ; i0 ) mask[i-1][j] |= MASK_LEAKED; if ( i0 ) mask[i][j-1] |= MASK_LEAKED; if ( jsx <=0 || i->sy <=0 || i->data==NULL ) /* invalid */ return(-1); else if ( bitpix<0 ) /* real data, do nothing */ return(0); else if ( bitpix==8 ) { llo=-128.0; lhi=+127.0; } else if ( bitpix==16 ) { llo=-32768.0; lhi=+32767.0; } else if ( bitpix==32 ) { llo=-2147483648.0; lhi=+2147483647.0; } else /* invalid bitpix value */ return(-1); for ( k=0 ; ksy ; k++ ) { for ( l=0 ; lsx ; l++ ) { if ( i->data[k][l]data[k][l]=llo; } else if ( i->data[k][l]>lhi ) { if ( mask != NULL ) mask[k][l] |= mvhi; if ( is_corr ) i->data[k][l]=lhi; } else if ( is_corr ) i->data[k][l]=floor(i->data[k][l]); } } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/star-draw.c0000644000175000017500000001452012771510030014110 0ustar apalapal/*****************************************************************************/ /* star-draw.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2004, 2005, 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include "math/expint/expint.h" #include "math/poly.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "tensor.h" #include "stars.h" #include "psf.h" int star_draw_gauss (double **iarr,int sx,int sy, double x0,double y0,double is,double id,double ik) { int i,j; double gs,gd,gk,det,dx,dy,is_deviated; static double **itensor=NULL; static int afsize=0; double *iverx,*ihorx,*iverf,*ihorf,*ilx,*ily; if ( iarr==NULL ) return(-1); if ( sx<=0 || sy<=0 ) return(-1); det=is*is-id*id-ik*ik; if ( det<=0.0 ) return(0); gs=(is*is+id*id+ik*ik)/(det*det), gd=-2*is*id/(det*det), gk=-2*is*ik/(det*det); if ( gk == 0.0 ) is_deviated=0; else is_deviated=1; if ( sx>afsize || sy>afsize || itensor==NULL ) { afsize=(sx>sy?sx:sy); if ( itensor != NULL ) tensor_free(itensor); itensor=(double **)tensor_alloc_2d(double,afsize+1,6); } ihorx=itensor[0],ihorf=itensor[1],ilx=itensor[2]; iverx=itensor[3],iverf=itensor[4],ily=itensor[5]; if ( ! is_deviated ) { double sqx,sqy; sqx=sqrt(0.5*(gs+gd)); sqy=sqrt(0.5*(gs-gd)); for ( j=0 ; j<=sx ; j++ ) { dx=(double)j-x0; ihorf[j]=erf(sqx*dx); } for ( i=0 ; i<=sy ; i++ ) { dy=(double)i-y0; iverf[i]=erf(sqy*dy); } for ( j=0 ; jafsize || sy>afsize || order>aorder) { afsize=(sx>sy?sx:sy); aorder=order; if ( ihorl != NULL ) tensor_free(ihorl); if ( iverl != NULL ) tensor_free(iverl); if ( fact != NULL ) tensor_free(fact); ihorl=(double **)tensor_alloc_2d(double,aorder+1,afsize+1); iverl=(double **)tensor_alloc_2d(double,aorder+1,afsize+1); fact =(double *)tensor_alloc_1d(double,(order+1)*(order+2)/2); for ( o=0,l=0,i=1 ; o<=order ; o++ ) { j=i; for ( k=0 ; k<=o ; k++,l++ ) { fact[l]=1.0/(double)(j); if ( korder+1)*(p->order+2)/2; bx=p->grid*(2*p->hsize+1); by=p->grid*(2*p->hsize+1); if ( bx>abx || by>aby ) { if ( bqc != NULL ) tensor_free(bqc); if ( coeff != NULL ) tensor_free(coeff); coeff=(double **)tensor_alloc_2d(double,bx,by); bqc =(double **)tensor_alloc_2d(double,2*bx+1,2*by+1); abx=bx,aby=by; } if ( nvar>anvar ) { if ( cpoly != NULL ) tensor_free(cpoly); cpoly=(double *)tensor_alloc_1d(double,nvar); anvar=nvar; } for ( i=0 ; icoeff[k][i][j]; } coeff[i][j]=eval_2d_poly(px,py,p->order,cpoly,p->ox,p->oy,p->scale); } } biquad_coeff(coeff,bx,by,bqc,NULL); afm=(double)p->grid; afo=(double)p->grid*(0.5+(double)p->hsize); for ( i=0 ; i=bx ) x1=bx; if ( x2<0.0 ) x2=0.0; if ( x2>=bx ) x2=bx; if ( y1<0.0 ) y1=0.0; if ( y1>=by ) y1=by; if ( y2<0.0 ) y2=0.0; if ( y2>=by ) y2=by; if ( x1==x2 || y1==y2 ) iarr[i][j]=0.0; else iarr[i][j]=biquad_isc_int_rectangle(bqc,x1,y1,x2,y2); } else { xdl=afm*(lmxx*x1+lmxy*y1)+afo,ydl=afm*(lmyx*x1+lmyy*y1)+afo; xdr=afm*(lmxx*x2+lmxy*y1)+afo,ydr=afm*(lmyx*x2+lmyy*y1)+afo; xul=afm*(lmxx*x1+lmxy*y2)+afo,yul=afm*(lmyx*x1+lmyy*y2)+afo; xur=afm*(lmxx*x2+lmxy*y2)+afo,yur=afm*(lmyx*x2+lmyy*y2)+afo; iarr[i][j]=biquad_isc_int_triangle(bqc,1,xdl,ydl,xdr,ydr,xul,yul,bx,by)+ biquad_isc_int_triangle(bqc,1,xdr,ydr,xur,yur,xul,yul,bx,by); } } } return(0); } fitsh-0.9.2/src/tensor.c0000644000175000017500000000406411200643553013523 0ustar apalapal/*****************************************************************************/ /* tensor.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for allocating tensors with arbitrary rank and type. */ /* (c) 2004, 2005; Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in tensor.h */ /*****************************************************************************/ #include #include #include #include #include #include "tensor.h" /*****************************************************************************/ void *tensor_alloc_arr(int typesize,int rank,int *arr) { int tsize,psize,bsize,cd,cb,snext,pnext; int i,j; void *ret,**pret; if ( rank<=0 ) return(NULL); psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { bsize=bsize*arr[i]; psize+=bsize; } psize=psize*sizeof(void *); tsize=psize+typesize*bsize*arr[0]; pret=(void **)malloc(tsize); if ( pret==NULL ) return(NULL); psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { cd=arr[i]; if ( i>1 ) snext=sizeof(void *); else snext=typesize; cb=cd*bsize; pnext=psize+cb; for ( j=0 ; j #include #include #include #include #include #include #include #include "io/tokenize.h" #include "fitsmask.h" #include "fitsh.h" /*****************************************************************************/ #define MASKDRAW_PIXEL 1 #define MASKDRAW_BLOCK 2 #define MASKDRAW_LINE 3 #define MASKDRAW_CIRCLE 4 /*****************************************************************************/ static int maskdraw_draw_block(char **mask,int sx,int sy, int maskval,int x0,int y0,int bx,int by) { int k,l; for ( k=0 ; k= sy ) continue; for ( l=0 ; l= sx ) continue; mask[y0+k][x0+l] |= maskval; } } return(0); } static int maskdraw_draw_pixel(char **mask,int sx,int sy, int maskval,int x0,int y0) { maskdraw_draw_block(mask,sx,sy,maskval,x0,y0,1,1); return(0); } static int maskdraw_draw_line(char **mask,int sx,int sy, int maskval,int x1,int y1,int x2,int y2,int width) { int len,lx,ly,i,x,y; lx=(x2>x1?x2-x1:x1-x2); ly=(y2>y1?y2-y1:y1-y2); len=(lx>ly?lx:ly); if ( width<0 ) width=0; if ( len<=0 ) { maskdraw_draw_block(mask,sx,sy,maskval,x1-width,y1-width,2*width+1,2*width+1); return(0); } for ( i=0 ; i<=len ; i++ ) { x=((2*x1+1)+2*(x2-x1)*i/len)/2; y=((2*y1+1)+2*(y2-y1)*i/len)/2; maskdraw_draw_block(mask,sx,sy,maskval,x-width,y-width,2*width+1,2*width+1); } return(0); } static int maskdraw_draw_circle(char **mask,int sx,int sy, int maskval,int x1,int y1,int radius) { int k,l,dx,dy2,r2; r2=radius*(radius+1); for ( k=y1-radius ; k<=y1+radius ; k++ ) { if ( ! ( 0<=k && k3 ) is_invalid=1; else if ( (maskval=parse_mask_flags(cc[0]))<0 ) is_invalid=2; else if ( sscanf(cc[1],"%d,%d",&x0,&y0)<2 ) is_invalid=3; else if ( n>=3 && sscanf(cc[2],"%d,%d",&bx,&by)<2 ) is_invalid=4; else is_invalid=0; if ( bx>=0 && by>=0 ) { bx=bx-x0+1; by=by-y0+1; } else { bx=1; by=1; } if ( ! is_invalid ) maskdraw_draw_block(mask,sx,sy,maskval,x0,y0,bx,by); } else if ( type==MASKDRAW_PIXEL ) { if ( n != 2 ) is_invalid=1; else if ( (maskval=parse_mask_flags(cc[0]))<0 ) is_invalid=2; else if ( sscanf(cc[1],"%d,%d",&x0,&y0)<2 ) is_invalid=3; else is_invalid=0; if ( ! is_invalid ) maskdraw_draw_pixel(mask,sx,sy,maskval,x0,y0); } else if ( type==MASKDRAW_LINE ) { w=0; if ( n<3 || n>4 ) is_invalid=1; else if ( (maskval=parse_mask_flags(cc[0]))<0 ) is_invalid=2; else if ( sscanf(cc[1],"%d,%d",&x0,&y0)<2 ) is_invalid=3; else if ( sscanf(cc[2],"%d,%d",&bx,&by)<2 ) is_invalid=3; else if ( n==4 && ( sscanf(cc[3],"%d",&w)<1 || w<0 ) ) is_invalid=3; else is_invalid=0; if ( ! is_invalid ) maskdraw_draw_line(mask,sx,sy,maskval,x0,y0,bx,by,w); } else if ( type==MASKDRAW_CIRCLE ) { w=0; if ( n != 3 ) is_invalid=1; else if ( (maskval=parse_mask_flags(cc[0]))<0 ) is_invalid=2; else if ( sscanf(cc[1],"%d,%d",&x0,&y0)<2 ) is_invalid=3; else if ( sscanf(cc[2],"%d",&br)<1 ) is_invalid=3; else is_invalid=0; if ( ! is_invalid ) maskdraw_draw_circle(mask,sx,sy,maskval,x0,y0,br); } else is_invalid=5; free(mtmp); return(is_invalid); } /*****************************************************************************/ fitsh-0.9.2/src/grmatch.c0000644000175000017500000015450412771247741013660 0ustar apalapal/*****************************************************************************/ /* grmatch.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line utility to match files based on: */ /* - two-dimensional point sets (point matching), */ /* - any dimensional coordinate sets (coordinate matching), and */ /* - identifiers (identifier matching). */ /*****************************************************************************/ #define FITSH_GRMATCH_VERSION "0.9d6" /*****************************************************************************/ #include #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "math/polyfit.h" #include "math/tpoint.h" #include "math/trimatch.h" #include "math/cpmatch.h" #include "transform.h" #include "common.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ #define MAX_COORDMATCH_DIM 5 /* To make sizeof(iline)=64, */ /* however, can be changed */ /* to arbitrary dimension... */ #define MATCH_POINTS 1 #define MATCH_IDS 2 #define MATCH_COORDS 3 #define MATCH_READ_COORDS 0x01 #define MATCH_READ_ID 0x02 /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ typedef struct { int *colcoords; int ncolcoord; int colord; int colwgh; int *colids; int ncolid; int neg_ordering; } colinfo; typedef struct { double x,y; } ilinepoint2d; typedef struct { double x[MAX_COORDMATCH_DIM]; } ilinepointnd; typedef union { ilinepoint2d d; ilinepointnd n; } ilinepoint; typedef struct { ilinepoint p; double ordseq,weight; char *line,*id; } iline; /*****************************************************************************/ int get_number_list(char *strcolid,int **rids,int *rnid) { int *ids,nid,c; ids=NULL; nid=0; while ( *strcolid ) { if ( sscanf(strcolid,"%d",&c)<1 || c<=0 ) { if ( ids != NULL ) free(ids); return(1); } ids=(int *)realloc(ids,sizeof(int)*(nid+1)); ids[nid]=c-1; nid++; while ( *strcolid && *strcolid != ',' ) strcolid++; if ( *strcolid==',' ) strcolid++; }; if ( rids != NULL ) *rids=ids; if ( rnid != NULL ) *rnid=nid; return(0); } int normalize_columns(colinfo *col,char *strcolcoord,char *strcolid) { if ( col->colord>0 ) col->colord--,col->neg_ordering=0; else if ( col->colord<0 ) col->colord=-col->colord-1,col->neg_ordering=1; else col->colord=-1; if ( strcolcoord==NULL ) { col->ncolcoord=2; col->colcoords=(int *)malloc(sizeof(int)*2); col->colcoords[0]=0; col->colcoords[1]=1; } else { if ( get_number_list(strcolcoord,&col->colcoords,&col->ncolcoord) ) return(1); } if ( strcolid==NULL ) { col->ncolid=1; col->colids=(int *)malloc(sizeof(int)); col->colids[0]=0; } else { if ( get_number_list(strcolid,&col->colids,&col->ncolid) ) return(1); } if ( col->colids==NULL ) return(1); else return(0); } static char *wrninappr="Warning: inappropriate content in line %d, skipped.\n"; int cut_newline(char *buff) { for ( ; *buff ; buff++ ) { if ( *buff==10 ) *buff=0; } return(0); } int read_match_data_points(FILE *fr,colinfo *col,iline **rils,int *rnil,int mtype) { char *rbuff,*sbuff,**cmd,*id; iline *ils; int nil,n,i,k,l,ln; double xrs[MAX_COORDMATCH_DIM],wo,ww; ils=NULL; nil=0; ln=0; rbuff=sbuff=NULL;cmd=NULL; while ( ! feof(fr) ) { if ( sbuff != NULL ) { free(sbuff);sbuff=NULL; } if ( rbuff != NULL ) { free(rbuff);rbuff=NULL; } if ( cmd != NULL ) { free(cmd); cmd =NULL; } rbuff=freadline(fr); if ( rbuff==NULL ) break; ln++; sbuff=strdup(rbuff); remove_newlines_and_comments(rbuff); cmd=tokenize_spaces_dyn(rbuff); if ( cmd==NULL ) continue; for ( n=0 ; cmd[n] != NULL ; ) n++; if ( n==0 ) continue; id=NULL; if ( mtype & MATCH_READ_COORDS ) { k=0; for ( i=0 ; incolcoord ; i++ ) { xrs[i]=0.0; if ( col->colcoords[i]colcoords[i]],"%lg",&xrs[i]); } if ( kncolcoord ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); continue; } } if ( mtype & MATCH_READ_ID ) { id=NULL;l=0; for ( i=0 ; incolid ; i++ ) { k=col->colids[i]; if ( 0<=k && kncolid ) { if ( id != NULL ) free(id); id=NULL; } if ( id==NULL ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); continue; } } if ( 0<=col->colord && col->colordcolord],"%lg",&wo); if ( k<1 || ! isfinite(wo) ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); continue; } if ( col->neg_ordering ) wo=-wo; } else wo=1.0; if ( 0<=col->colwgh && col->colwghcolwgh],"%lg",&ww); if ( k<1 || ! isfinite(ww) ) { if ( is_verbose ) fprintf(stderr,wrninappr,ln); continue; } } else ww=0.0; ils=(iline *)realloc(ils,sizeof(iline)*(nil+1)); for ( i=0 ; incolcoord ; i++ ) { ils[nil].p.n.x[i]=xrs[i]; } ils[nil].ordseq=wo; ils[nil].weight=ww; cut_newline(sbuff); ils[nil].line=sbuff,sbuff=NULL; ils[nil].id=id; nil++; }; if ( sbuff != NULL ) free(sbuff); if ( rbuff != NULL ) free(rbuff); if ( cmd != NULL ) free(cmd); *rils=ils; *rnil=nil; return(0); } /*****************************************************************************/ /* get_unitarity(): deprecated, use calc_2d_unitarity() from poly.c instead */ /* double get_unitarity(double ma,double mb,double mc,double md) { double n1,n2,nn,dd; n1=(ma-md)*(ma-md)+(mb+mc)*(mb+mc); n2=(ma+md)*(ma+md)+(mb-mc)*(mb-mc); nn=(n1ordseq < ((iline*)vi2)->ordseq ) return(1); else return(-1); } int do_pointmatch(iline *refls,int nref,iline *inpls,int ninp, matchpointtune *mptp,cphit **rhits,int *rnhit,int order,double **vfits, matchpointstat *mps) { tpoint *refps,*rftps,*inpps,*wp; point *pfits; tpointarr arrref,arrinp; cphit *hits; int nhit,i,j,k,nmin,ntriref,ntriinp; int i_iter,nmiter,tri_level; double rejlevel,x,y,w; double *xfit,*yfit; trimatchpar tmp; trimatchlog tml; iline *wi; double time_trimatch,time_symmatch,time_total; clock_t t0,t1; t0=clock(); nmiter=mptp->nmiter; if ( nmiter<=0 ) nmiter=0; rejlevel=mptp->rejlevel; if ( rejlevel<=0.0 ) nmiter=0; if ( mptp->use_ordering ) { qsort(inpls,ninp,sizeof(iline),match_compare_ordering); qsort(refls,nref,sizeof(iline),match_compare_ordering); } xfit=vfits[0]; yfit=vfits[1]; refps=(tpoint *)malloc(sizeof(tpoint)*nref); inpps=(tpoint *)malloc(sizeof(tpoint)*ninp); rftps=(tpoint *)malloc(sizeof(tpoint)*nref); hits=NULL; time_trimatch=0.0; time_symmatch=0.0; tri_level=0; for ( i_iter=0 ; i_iter<=nmiter ; i_iter++ ) { clock_t t0,t1; if ( i_iter<=0 ) { for ( i=0 ; iid=i; /* trivial id */ wp->xcoord=refls[i].p.d.x, wp->ycoord=refls[i].p.d.y; } } else { for ( i=0 ; iid=i; x=refls[i].p.d.x, y=refls[i].p.d.y; wp->xcoord=eval_2d_poly(x,y,order,xfit,0,0,1); wp->ycoord=eval_2d_poly(x,y,order,yfit,0,0,1); } } for ( i=0 ; iid=i; /* trivial id */ wp->xcoord=inpls[i].p.d.x, wp->ycoord=inpls[i].p.d.y; } hits=NULL; tmp.level =mptp->ttype; tmp.maxdist =-1.0; tmp.unitarity=mptp->unitarity; tmp.parity =mptp->parity; if ( ninp>nref ) nmin=nref; else nmin=ninp; if ( mptp->use_ordering && mptp->maxnum_inp>0 && mptp->maxnum_ref>0 ) { if ( nref>=mptp->maxnum_ref && ninp>=mptp->maxnum_inp ) { ntriref=mptp->maxnum_ref; ntriinp=mptp->maxnum_inp; } else { double nimr,nrmi; ntriref=nref; ntriinp=ninp; nimr=(double)ntriinp*(double)mptp->maxnum_ref; nrmi=(double)ntriref*(double)mptp->maxnum_inp; if ( nimr<=nrmi ) { ntriref=(int)(nimr/(double)mptp->maxnum_inp); } else { ntriinp=(int)(nrmi/(double)mptp->maxnum_ref); } if ( ntriref>mptp->maxnum_ref ) ntriref=mptp->maxnum_ref; if ( ntriinp>mptp->maxnum_inp ) ntriinp=mptp->maxnum_inp; if ( ntriref>nref ) ntriref=nref; if ( ntriinp>ninp ) ntriinp=ninp; } } else if ( mptp->use_ordering ) { ntriref=nmin; ntriinp=nmin; } else { ntriref=nref, ntriinp=ninp; } /*fprintf(stderr,"nref=%d,ninp=%d;mxref=%d,mxinp=%d;ntriref=%d,ntriinp=%d\n",nref,ninp,mptp->maxnum_ref,mptp->maxnum_inp,ntriref,ntriinp);*/ if ( hits != NULL ) { free(hits); hits=NULL; } t0=clock(); trimatch(refps,ntriref,inpps,ntriinp,order,&tmp,&hits,&nhit,xfit,yfit,&tml); t1=clock(); time_trimatch+=(double)(t1-t0)/(double)CLOCKS_PER_SEC; if ( tml.level_used > tri_level ) tri_level=tml.level_used; /* fprintf(stderr,"x: -> %12g %12g %12g\n",xfit[0],xfit[1],xfit[2]); fprintf(stderr,"y: -> %12g %12g %12g\n",yfit[0],yfit[1],yfit[2]); */ for ( i=0 ; imaxdist); /*hits=cpmatch_symmetric(&arrref,&arrinp,&nhit,3.0,0.0);*/ /* old */ t1=clock(); time_symmatch+=(double)(t1-t0)/(double)CLOCKS_PER_SEC; pfits=(point *)malloc(sizeof(point)*nhit); for ( i=0 ; iwcat>=0 ) { for ( i=0 ; iwcat ) wi=&refls[hits[i].idx[0]]; else wi=&inpls[hits[i].idx[1]]; w=wi->weight; if ( mptp->w_magnitude ) { w=exp(-0.4*M_LN10*(w-20.0)); } if ( mptp->wpower != 1.0 ) { w=pow(w,mptp->wpower); } pfits[i].weight=w; } } for ( i=0 ; iis_centering && mptp->maxcenterdist>0.0 ) { x=eval_2d_poly(mptp->refcx,mptp->refcy,order,xfit,0,0,1)-mptp->inpcx; y=eval_2d_poly(mptp->refcx,mptp->refcy,order,yfit,0,0,1)-mptp->inpcy; if ( x*x+y*y > mptp->maxcenterdist*mptp->maxcenterdist ) break; } } t1=clock(); time_total=(double)(t1-t0)/(double)CLOCKS_PER_SEC; if ( mps != NULL ) { mps->time_total=time_total; mps->time_trimatch=time_trimatch; mps->time_symmatch=time_symmatch; mps->nmiter=nmiter+1; mps->tri_level=tri_level; } if ( mps != NULL && nhit>0 ) { double ws,ns,wdd,ndd,nx,ny,dx,dy,dd; ws=wdd=0.0; ns=ndd=0.0; for ( i=0 ; iwcat<0 ) wi=NULL; else if ( ! mptp->wcat ) wi=&refls[j]; else wi=&inpls[k]; if ( wi != NULL ) { w=wi->weight; if ( mptp->w_magnitude ) { w=exp(-0.4*M_LN10*(w-20.0)); } if ( mptp->wpower != 1.0 ) { w=pow(w,mptp->wpower); } } else w=1.0; x=refls[j].p.d.x, y=refls[j].p.d.y; nx=eval_2d_poly(x,y,order,xfit,0,0,1); ny=eval_2d_poly(x,y,order,yfit,0,0,1); dx=nx-inpls[k].p.d.x; dy=ny-inpls[k].p.d.y; dd=dx*dx+dy*dy; ws+=w, wdd+=dd*w; ns+=1.0,ndd+=dd; } if ( ws>0.0 ) mps->wsigma=sqrt(wdd/ws); else mps->wsigma=0.0; if ( ns>0.0 ) mps->nsigma=sqrt(ndd/ns); else mps->nsigma=0.0; mps->unitarity=calc_2d_unitarity(xfit,yfit,order); } else if ( mps != NULL ) { mps->wsigma=0.0; mps->nsigma=0.0; mps->unitarity=-1.0; } free(rftps); free(inpps); free(refps); if ( rhits != NULL ) *rhits=hits; if ( rnhit != NULL ) *rnhit=nhit; return(0); } /*****************************************************************************/ int match_compare_firstcoord(const void *vi1,const void *vi2) { if ( ((iline*)vi1)->p.n.x[0] < ((iline*)vi2)->p.n.x[0] ) return(-1); else return(1); } int coordmatch_search_nearest(iline *ils,int nil,double *x0,int dim) { int best,min,max,mid,i,j,brk; double *xc,xc0[MAX_COORDMATCH_DIM], xx,cc,dd,dist[MAX_COORDMATCH_DIM],cdist,edist,mindist,maxdist; int outl,outr,pl,pr; if ( ils==NULL || nil<=0 || x0==NULL || dim<=0 || dim>MAX_COORDMATCH_DIM ) return(0); min=mid=0; max=nil; while ( max>min ) { mid=(min+max)/2; cdist=x0[0]-ils[mid].p.n.x[0]; if ( fabs(cdist)<1e-10 ) break; else if ( cdist>0.0 ) min=mid+1; else max=mid; } /* one dimension: it is a special (and simple) case... */ if ( dim==1 ) { best=mid; mindist=fabs(x0[0]-ils[mid].p.n.x[0]); if ( mid>0 ) { cdist=fabs(x0[0]-ils[mid-1].p.n.x[0]); if ( cdist=0 ) { xc=&ils[pl].p.n.x[0]; xx=fabs(x0[0]-xc[0]); if ( xx0 ; dim--,x1++,x2++ ) { r+=((*x1)-(*x2))*((*x1)-(*x2)); } return(r); } int do_coordmatch(iline *refls,int nref,iline *inpls,int ninp,cphit **rhits,int *rnhit,int dim,double maxdist) { cphit *hits; int nmin,*refhs,*inphs,i,j,nhit; double mxd2; if ( refls==NULL || nref<=0 ) return(-1); if ( inpls==NULL || ninp<=0 ) return(-1); qsort(refls,nref,sizeof(iline),match_compare_firstcoord); qsort(inpls,ninp,sizeof(iline),match_compare_firstcoord); nmin=(nref>ninp?ninp:nref); hits=(cphit *)malloc(sizeof(cphit)*nmin); refhs=(int *)malloc(sizeof(int)*nref); inphs=(int *)malloc(sizeof(int)*ninp); for ( i=0 ; iid,((iline*)vi2)->id) ); } /* int search_id(iline *inpls,int n,char *id) { int f,k,w; f=0; while ( n ) { k=f+n/2; w=stridcmp(inpls[k].id,id); if ( w==0 ) return(k); else if ( w<0 ) f+=n/2+1,n-=n/2+1; else n=n/2; }; return(-1); } */ int search_id_limiters(iline *inpls,int n,char *id,int *rleft,int *rright) { int min,mid,max; if ( n<=0 ) return(1); if ( rleft==NULL || rright==NULL ) return(-1); min=0,max=n; if ( ! ( 0<=stridcmp(inpls[n-1].id,id) ) ) { *rleft=1,*rright=0; return(1); } while ( max>min+1 ) { mid=(min+max)/2; if ( 0<=stridcmp(inpls[mid-1].id,id) ) max=mid; else min=mid; }; *rleft=min; min=0,max=n; if ( ! ( stridcmp(inpls[0].id,id)<=0 ) ) { *rleft=1,*rright=0; return(1); } while ( max>min+1 ) { mid=(min+max)/2; if ( stridcmp(inpls[mid].id,id)<=0 ) min=mid; else max=mid; }; *rright=min; if ( *rleft>*rright ) return(1); else return(0); } #define AMBIG_NONE 0 #define AMBIG_FIRST 1 #define AMBIG_ANY 2 #define AMBIG_FULL 3 int do_idmatch(iline *refls,int nref,iline *inpls,int ninp,cphit **rhits,int *rnhit,int ambig) { int i,j,k,nhit,ahit,hr,hi,rl,rr,il,ir; cphit *hits; char *id; qsort(inpls,ninp,sizeof(iline),id_compare); qsort(refls,nref,sizeof(iline),id_compare); ahit=nref; hits=(cphit *)malloc(sizeof(cphit)*ahit); nhit=0; for ( i=0 ; iahit ) { ahit=nhit+k; hits=(cphit *)realloc(hits,sizeof(cphit)*ahit); } switch ( ambig ) { case AMBIG_FIRST: hits[nhit].idx[0]=rl; hits[nhit].idx[1]=il; nhit++; break; case AMBIG_ANY: for ( j=0 ; j


[[-i|--input] ] [-o|--output ]\n" "Point matching (default, --match-points can be omitted):\n" "\t--match-points [--col-ref <>,<>] [--col-inp <>,<>] \n" "\t[--col-ref-ordering [-]<> --col-inp-ordering [-]<>]\n" "\t[--output-transformation ]\n" "\t[-a|--order ] [-f|--offset ,] [--scale ]\n"); fprintf(fw, "Identifier matching:\n" "\t--match-id [--col-ref-id <>[,<>[,...]]] [--col-inp-id <>[,<>[,...]]]\n" "\t[--{no|first|any|full}-ambiguity]\n"); fprintf(fw, "Coordinate matching:\n" "\t--match-coords [--col-ref <>[,<>[,...]]] [--col-inp <>[,<>[,...]]]\n" "\t[-m|--max-distance ]\n"); fprintf(fw, "Outputs:\n" "\t[--output|--output-matched|-o ] [--output-id ]\n" "\t[--output-excluded-{reference|input} ]\n"); fprintf(fw, "Fine-tuning of point matching:\n" "\t[-H|--hint-transformation [-b|--hint-order ]]\n" "\t[--triangulation delaunay|level=|full|auto[,unitarity=],\n" "\t mixed|conformable|reverse \n" "\t max{number|ref|inp}=]\n" "\t[-m|--max-distance ]\n" "\t[--fit iterations=,firstrejection=<1st.rej.>,sigma=]\n" "\t[--weight [reference|input],column=<>,[magnitude],[power=]\n" "\t[--center-{reference|input} , [--center-maxdist ]]\n"); return(0); } longhelp_entry grmatch_long_help[] = { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Give general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Give some version information about the program." }, { "-C, --comment", "Comment the output (both the transformation file and the match file)." }, { "Options for input/output specifications:", NULL }, { "-r , --input-reference ", "Mandatory, name of the reference file." }, { ", -i , --input ", "Name of the input file. If this switch is omitted, the input is" "read from stdin (specifying some input is mandatory)." }, { "-o , --output , --output-matched ", "Name of the output file, containing the matched lines. The " "matched lines are pasted lines, the first part is from the " "reference file and the second part is from the input file, these " "two parts are concatenated by a TAB character. This switch is " " optional, if it is not specified, no such output will " "be generated. " }, { "--output-excluded-reference , --output-excluded-input ", "Names of the files which contain the valid but excluded lines " "from the reference and from the input. These outputs are " "disjoint from the previous output and altogether contaions all " "valid lines." }, { "--output-id ", "Name of the file which contaions only the identifiers of the " "matched lines. If the primary matching method was not " "identifier matching, one should specify the column indices of the " "identifiers by --col-ref-id and --col-inp-id also." }, { "--output-transformation ", "Name of the output file containing the geometrical transformation, " "in human-readable format, if the matching method was point " "matching (in other case, this option has no effect). The " " commented version of this file includes some statistics about " "the matching (the total number of lines used and matched, " "the required CPU time, the final triangulation level, the fit " "residuals and other things like these)." }, { "In all of the above input/output file specifications, the replacement " "of the file name by \"-\" (a single minus sign) forces the reading from " "stdin or writing to stdout. Note that all parts of the any line after " "\"#\" (hashmark) are treated as a comment, therefore " "ignored. ", NULL }, { "", NULL }, { "General options for point matching:", NULL }, { "--match-points", "This switch forces the usage of the point matching method. By " "default, this method is assumed to be used, therefore this " "switch can be omitted." }, { "--col-ref ,, --col-inp ,", "The column indices containing the X and Y coordinates, for the " "reference and for the input file, respectively. The index of the " "first column is always 1, the index of the second is 2 and so " "on. Lines in which these columns do not contain valid real numbers " "bers are omitted." }, { "-a , --order ", "This switch specifies the polynomial order of the resulted " "geometrical transformation. It can be arbitrary positive integer. " "Note that if the order is A, at least (A+1)*(A+2)/2 valid points " "are needed both from the reference and both from the input file " "to fit the transformation. " }, { "--max-distance ", __extension__ "The maximal accepted distance between the matched points in the " "coordinate frame of the input coordinate list (and not in the " "coordinate frame of the reference coordinate list). Possible pairs " "(which are valid pairs due to " "the symmetric coordinate matching algorihms) are excluded if " "their Eucledian distance is larger than maxdist. Note that this " "option has no initial value, therefore, if omitted, all possible " "pairs due to the symmetric matching are resulted, which, in certain " "cases in practice, can result unexpected behaviour. One " "should always specify a reasonable maximal distance which can be " "estimated only by the knowledge of the physics of the input " "files. " }, { "See more options concerning to point matching in the section " "\"Fine-Tuning of Point Matching\" below. That section also " "describes the tuning of the triangulation used by the point " "matching algorithm. For a more detailed description about the " "point matching algorithms based on pattern and triangle matching " "see [1], [2] or [3].", NULL }, { "", NULL }, { "General options for coordinate matching:", NULL }, { "--match-coord, --match-coords", "This switch forces the usage of the coordinate matching method. " "Note that because of the common options with the point matching " "method, one should specify this switch to force the usage of the " "coordinate matching method (the default method is point matching, " "see above)." }, { "--col-ref [,,[...]] --col-inp [,,[...]]", __extension__ "The column indices containing the spatial coordinates, for the " "reference and for the input file, respectively. The index of the " "first column is always 1, the index of the second is 2 and so " "on. Lines in which these columns do not contain valid real numbers " "are omitted. Note that the dimension of the coordinate " "matching space is specified indirectly, by the number of column " "indices listed here. Because of this, the number of column " "indices should be the same for the reference and input, in other " "case, when the dimensions are mismatched, the program exits " "unsuccessfully." }, { "--max-distance ", "The maximal accepted distance between the matched points. " "Possible pairs (which are valid pairs due to the symmetric " "coordinate matching algorihms) are excluded if their Eucledian " "distance is larger than maxdist. Note that this option has no " "initial value, therefore, if omitted, all possible pairs due to " "the symmetric matching are resulted (see also point matching, " "above)." }, { "", NULL }, { "General options for identifier matching:", NULL }, { "--match-id, --match-identifiers", "This switch forces the usage of the identifier matching method." }, { "--col-ref-id [,,[...]] --col-inp-id [,,[...]]", "Column index or indices containing the identifiers, from the " "reference and from the input file, respectively." }, { "--no-ambiguity, --first-ambiguity, --any-ambiguity, --full-ambiguity", __extension__ "These options tune the behaviour of the matching when there is " "more than one occurrence of a given identifier in the reference " "and/or input file. If --no-ambiguity is specified, these " "identifiers are discarded, this is the default method. " "If --first-ambiguity is specified, only the first occurence is " "treated as a matched line, independently from the number of " "occurrences. If the switch --any-ambiguity is specified, the " "lines are paired sequentally, until there is any left from the " "reference and from the input. For example, if there is 4 " "occurrences in the reference and 6 in the input file of a given " "identifier, 4 matched pairs are returned. Otherwise, if " "--full-ambiguity is specified, all possible combinations " "of the lines are treated as matched lines. For example, if " "there is 4 occurrences in the reference and 6 in the " "input file of a given identifier, all 4*6=24 combinations are " "returned as matched pairs." }, { "Fine-tuning of point matching:", NULL }, { "--triangulation ", "This switch is followed by comma-separated directives, which " "specify the parameters of the triangulation-based point matching " "algorithm: " }, { "delaunay, level=, full, auto, unitarity=", __extension__ "These directives specify the triangulation level used for point " "matching. \"delaunay\" forces the usage only of the " "Delaunay-triangles. This is the fastest method, however, it is " "only working if the points in the reference and input lists are " "almost competely overlapping and describe almost the same " "point sets (within a ratio of common points above 60-70%). " "The \"level\" specifies the level of the expansion of the " "Delaunay-triangulation (see [1] for more details). In practice, " "the lower the ratio of common points and/or the ratio of the " "overlapping, the higher level should be used. Specifying " "\"level=1\" or \"level=2\" gives a robust but still fast " "method for general usage. The directive \"full\" forces full " "triangulation. This can be overwhelmingly slow and annoying " "and requires tons of memory if there are more than 40-50 points " "(the amounts of these resources are proportional to the 6th(!) " "and 3rd power of the number of the points, respectively). The " "directive \"auto\" increases the level of the triangulation " "expansion automatically until a proper match is found. A match " "is considered as a good match if the unitarity of the transformation " "is less than the unitarity U specified by the \"unitarity=U\" " "directive (see also the section Notes/Unitarity below). " }, { "mixed, conformable, reverse", __extension__ "These directives define the chirality of the triangle spaces to " "be used. Practically, it means the following. If we don't know " "whether the input and reference lists are inverted respecting to " "each other, one should use \"mixed\" triangle space. If we " "are sure about that the input and reference lists are not inverted, " "we can use \"conformable\" triangle space. If we know that the " "input and reference lists are inverted, we can use \"reverse\" " "space. Note that although \"mixed\" triangle space can always " "result a good match, it is a wise idea to fix the chirality by " "specifying \"conformable\" or \"reverse\" if we really know that " "the point sets are not inverted or inverted respecting " "to each other. If the chirality is fixed, the program yields " "more matched pairs, the appropriate triangulation level can " "be smaller and in \"auto\" mode, the program returns the match " "definitely faster." }, { "maxnumber=, maxref=, maxinp=", __extension__ "These directives specify the maximal number of points which are " "used for triangulation (for any type of triangulation). " "If \"maxnumber\" is specified, it is equivalent to define " "\"maxref\" and \"maxinp\" with the same values. Then, the " "first points from the reference and the first points " "from the input list are used to generate the triangle sets. " "The \"first\" points are selected using the optional " "information found in one of the columns, see the " "following switches." }, { "(Note that there should be only one --triangulation switch, all desired " "directives should be written in the same argument, " "separated by commas.)", NULL }, { "", NULL }, { "--col-ref-ordering [-], --col-inp-ordering [-].", __extension__ "These switches specify one-one column index from the reference " "and from the input files which are used to order these lists and " "select the first \"maxref\" and \"maxinp\" points (see above) " "for the generation of the two triangle meshes. Both columns " "should contain valid real numbers, otherwise the whole(!) " "line is excluded (not only from sorting but from the whole matching " "procedure). If there is no negative sign before the column index, " "the data are sorted in descending(!) order, therefore the lines " "with the lines with the highest(!) values are selected for " "triangulation. If there is a negative sign before the index, " "the data are sorted in ascending order by these values, " "therefore the lines with the smallest(!) values are selected for " "triangulation. For example, if we want to match star lists, we " "might want to use only the brightest ones to generate the " "triangle sets. If the brightnesses of the stars are specified " "by their fluxes, we should not use the negative sign (the list " "should be sorted in descending order to select the first few " "lines as the brightest stars), and if the brightness is known " "by the magnitude, we have to use the negative sign." }, { "--fit iterations=,firstrejection=,sigma=", __extension__ "Like --triangulation, this switch is followed by some " "directives. These directives specify the number of " "iterations (\"iterations=\") for point matching. The " "\"firstrejection\" directive speciy the serial number " "of the first iteration where points farer than \"sigma\" level " "are excluded in the next iteration. Note that in practice " "these type of iteration is really not important (due to, for instance, " "the limitations of the outliers by the --max-distance switch), " "however, some suspicious users can be convinced by such arguments." }, { "--weight reference|input,column=,[magnitude],[power=

]", __extension__ "These directives specify the weights which are used during the " "fit of the geometrical transformation. For example, in practice " "it is useful in the following situation. We try to match star " "lists, then the fainter stars are believed to have higher " "astrometrical errors, therefore they should have smaller influence " "in the fit. We can take the weights from the reference " "(specify \"reference\") and from the input (specify \"input\"), " "from the column specified by the weight-index. The weights can " "be derived from stellar magnitudes, if so, specify \"magnitude\" " "to convert the read values in magnitude to flux. The real weights " "then is the \"power\"th power of the flux. The default " "value of the \"power\" is 1, however, for the maximum-likelihood " "estimation of an assumed Gaussian distribution, the weights " "should be the second power of the fluxes." }, { __extension__ "Some notes on unitarity. The unitarity of a geometrical transformation " "measures how it differs from the closest transformation which is affine " "and a combination of dilation, rotation and shift. For such a " "transformation the unitarity is 0 and if the second-order terms in " "a transformation distort a such unitary transformation, the unitarity " "will have the same magnitude like the magnitude of this second-order " "effect. For example, to map a part of a sphere with the size of d degrees " "will have an unitarity of 1-cos(d). Therefore, for astrometrical " "purposes, a reasonable value of the critical unitarity in \"auto\" " "triangulation mode can be estimated as 2 or 3 times 1-cos(d/2) " "where d is the size of the field in which astrometry " "should be performed.", NULL }, { "", NULL }, { NULL, NULL } }; int fprint_grmatch_long_help(FILE *fw,int is_wiki) { char *synopsis= "grmatch [options] -r -i [-o ]"; char *description= __extension__ "The program `grmatch` matches lines read from two input files, namely " "from a reference and from an input file. All implemented algorithms are " "symmetric, in the manner that the result should be the same if these " "two files are " "swapped. The only case when the order of these files is important is when " "a geometrical transformation is also returned (see point matching below), " "in this case the swapping of the files results the inverse form of the " "original transformation. " "The lines (rows) can be matched using various criteria. " "1. Lines can be matched by identifier, where the identifier can " "be any concatenation of arbitrary, space-separated columns found in the " "files. Generally, the identifier is represented by a single column " "(e.g. it is an astronomical catalog identifier). The behaviour of the " "program can be tuned for the cases when there are more than one rows " "with the same identifier. " "2. Lines can be matched using a 2-dimensional point matchig algorithm. " "In this method, the program expects two-two columns both from the " "reference and input files which can be treated as X and Y coordinates. " "If both point lists are known, the program tries to find the appropriate " "geometrical transformation which transforms the points from the " "frame of the reference list to the frame of the input list and, " "simultaneously, tries to find as many pairs as possible. The " "parameters of the geometrical transformation and the whole algorithm " "can be fine-tuned. " "3. Lines can be matched using arbitrary- (N-) dimensional coordinate matching " "algorithm. This method expects N-N columns both from the " "reference and input files which can be treated as X_1, ..., X_N Cartesian " "coordinates and the method assumes both of the point sets in the " "same reference frame. The point 'A' from the reference list and " "the point 'P' from the input list forms a pair if the closest point " "to 'A' from the input list is 'P' and vice versa."; fprint_generic_long_help(fw,is_wiki,grmatch_long_help,synopsis,description); return(0); } /*****************************************************************************/ int fprint_pointmatch_stat(FILE *fw,int nhit,int nref,int ninp,matchpointstat *mps) { double rat; fprintf(fw,"# Residual: %g (native)\n",mps->nsigma); fprintf(fw,"# Residual: %g (weighted)\n",mps->wsigma); fprintf(fw,"# Unitarity: %g\n",mps->unitarity); fprintf(fw,"# Points: %d %d %d (number of: matched, reference, input)\n",nhit,nref,ninp); if ( ninptime_total,mps->time_trimatch,mps->time_symmatch,mps->nmiter); fprintf(fw,"# Triangulation: %d (maximal triangulation level)\n",mps->tri_level); fprintf(fw,"# All: %g %g %g %d %d %d %.2f %.3f %.3f %.3f %d %d\n", mps->nsigma,mps->wsigma,mps->unitarity, nhit,nref,ninp,rat*100.0, mps->time_total,mps->time_trimatch,mps->time_symmatch, mps->nmiter,mps->tri_level); return(0); } int fprint_general_stat(FILE *fw,int nhit,int nref,int ninp) { double rat; if ( ninp=0 && colinp.colord>=0 ) mptp.use_ordering=1; else mptp.use_ordering=0; if ( triparam != NULL ) { int is_auto; int maxnum; is_auto=0; maxnum=0; i=scanpar(triparam,SCANPAR_DEFAULT, "full:%SN-1f",&mptp.ttype, "delaunay:%SN0f",&mptp.ttype, "level:%d",&mptp.ttype, "auto:%f",&is_auto, "maxnumber:%d",&maxnum, "maxref|maxnumref|maxrefnum:%d",&mptp.maxnum_ref, "maxinp|maxnuminp|maxinpnum:%d",&mptp.maxnum_inp, "unitarity:%g",&mptp.unitarity, "mixed:%SN0f",&mptp.parity, "conformable:%SN1f",&mptp.parity, "reverse:%SN-1f",&mptp.parity, NULL); if ( i ) { fprint_error("invalid triangulation parameter in '%s'",triparam); return(1); } if ( maxnum>0 ) { mptp.maxnum_ref=maxnum; mptp.maxnum_inp=maxnum; } if ( ! is_auto ) mptp.unitarity=0.0; else if ( mptp.unitarity<=0.0 ) mptp.unitarity=0.005; } if ( fitparam != NULL ) { i=scanpar(fitparam,SCANPAR_DEFAULT, "iterations:%d",&mptp.nmiter, "firstrejection:%d",&mptp.friter, "sigma:%g",&mptp.rejlevel, NULL); if ( i ) { fprint_error("invalid fit parameter in '%s'",fitparam); return(1); } } if ( wghparam != NULL ) { int wcat,wcol,is_mag; double power; wcat=0;wcol=1; is_mag=0; power=1.0; i=scanpar(wghparam,SCANPAR_DEFAULT, "reference:" SNf(0), &wcat, "input:" SNf(1), &wcat, "column:%d",&wcol, "magnitude:%f",&is_mag, "power:%g",&power, NULL); if ( i || wcol<=0 ) { fprint_error("invalid weight parameter in '%s'",wghparam); return(1); } mptp.wcat=wcat; mptp.wpower=power; mptp.w_magnitude=is_mag; if ( ! wcat ) colref.colwgh=wcol-1; else colinp.colwgh=wcol-1; } else { mptp.wcat=-1; mptp.wpower=0.0; mptp.w_magnitude=0; } if ( mptp.is_centering != 3 ) mptp.is_centering=0; else mptp.is_centering=1; if ( mptp.maxcenterdist<0.0 ) mptp.maxcenterdist=0.0; if ( reffile==NULL ) { fprint_error("no reference file has been specified"); return(1); } fr=fopenread(reffile); if ( fr==NULL ) { fprint_error("unable to open reference file '%s'",reffile); return(1); } read_match_data_points(fr,&colref,&refls,&nref,matchread); fcloseread(fr); if ( infile==NULL ) fr=stdin; else fr=fopenread(infile); if ( fr==NULL ) { fprint_error("unable to open input file '%s'",infile); return(1); } read_match_data_points(fr,&colinp,&inpls,&ninp,matchread); fcloseread(fr); if ( intransfile != NULL ) { FILE *ft; ft=fopenread(intransfile); if ( ft==NULL ) { fprint_error("unable to open input transformation file '%s'",intransfile); return(1); } i=transformation_read_data(ft,itf); if ( i ) { fprint_error("unable to parse transformation data in '%s'",intransfile); return(1); } if ( itf->nval != 2 ) { fprint_error("transformation is not a 2D -> 2D one"); return(1); } fcloseread(ft); } else if ( intransparam != NULL ) { i=transformation_parse_params(intransparam,itf); if ( i ) { fprint_error("unable to parse transformation string '%s'",intransparam); return(1); } if ( itf->nval != 2 ) { fprint_error("transformation is not a 2D -> 2D one"); return(1); } } else itf=NULL; if ( hntransfile != NULL ) { FILE *ft; ft=fopenread(hntransfile); if ( ft==NULL ) { fprint_error("unable to open hint transformation file '%s'",hntransfile); return(1); } i=transformation_read_data(ft,htf); if ( i ) { fprint_error("unable to parse transformation data in '%s'",intransfile); return(1); } if ( htf->nval != 2 ) { fprint_error("hint transformation is not a 2D -> 2D one"); return(1); } fcloseread(ft); if ( hintorder <= 0 ) hintorder=order; } else htf=NULL; nvar=(order+1)*(order+2)/2; vfits=(double **)malloc(sizeof(double *)*2); vfits[0]=xfit=(double *)malloc(sizeof(double)*nvar); vfits[1]=yfit=(double *)malloc(sizeof(double)*nvar); hits=NULL; nhit=0; switch ( matchtype ) { case MATCH_POINTS: mptp.htf=htf; mptp.hintorder=hintorder; do_pointmatch(refls,nref,inpls,ninp,&mptp,&hits,&nhit,order,vfits,&mps); if ( nhit<=0 ) is_failed=1; else if ( ! isfinite(mps.unitarity) ) is_failed=1,mps.unitarity=-1; else if ( mps.unitarity<0.0 ) is_failed=1; else is_failed=0; for ( i=0 ; i<(order+1)*(order+2)/2 ; i++ ) { if ( ! isfinite(vfits[0][i]) ) is_failed=1; if ( ! isfinite(vfits[1][i]) ) is_failed=1; } if ( is_failed ) { for ( i=0 ; i<(order+1)*(order+2)/2 ; i++ ) { vfits[0][i]=0.0; vfits[1][i]=0.0; } mps.wsigma=0.0; mps.nsigma=0.0; } break; case MATCH_COORDS: do_coordmatch(refls,nref,inpls,ninp,&hits,&nhit,colref.ncolcoord,mptp.maxdist); if ( nhit<=0 ) is_failed=1; else is_failed=0; /* almost always successful */ break; case MATCH_IDS: do_idmatch(refls,nref,inpls,ninp,&hits,&nhit,ambig); if ( nhit<=0 ) is_failed=1; else is_failed=0; /* almost always successful */ break; default: hits=NULL; nhit=0; is_failed=1; break; } if ( hits==NULL ) nhit=0; if ( outfile != NULL && hits != NULL && nhit>0 ) { fw=fopenwrite(outfile); if ( fw==NULL ) { fprint_error("unable to create output file '%s'",outfile); return(1); } for ( i=0 ; i0 ) { int mxr,mxi,l; char sbuff[32],*ir,*ii; fw=fopenwrite(outidfile); if ( fw==NULL ) { fprint_error("unable to create output identifier list file '%s'",outidfile); return(1); } mxr=mxi=1; for ( i=0 ; imxr ) mxr=l; } if ( inpls[l2].id != NULL ) { l=strlen(inpls[l2].id);if ( l>mxi ) mxi=l; } } sprintf(sbuff,"%%%ds\t%%%ds\n",mxr,mxi); for ( i=0 ; itype=TRANS_POLYNOMIAL; otf->order=order; otf->ox=otf->oy=0.0,otf->scale=1.0; otf->nval=2; otf->vfits=vfits; transformation_write_data(fw,otf,(is_comment?TRANS_WR_COMMENT:0)|TRANS_WR_DXDY); if ( is_comment ) { fprint_pointmatch_stat(fw,nhit,nref,ninp,&mps); if ( is_failed ) fprintf(fw,"# Match failed.\n"); } fclosewrite(fw); } /* if matching is failed, errorlevel will be 2: we follow DOS conventions, */ /* where higher return code represent less-critical error (invalid command */ /* line argument, invalid input/output file or such critical errors will */ /* return 1 as exit status). */ if ( is_failed ) return(2); else return(0); } fitsh-0.9.2/src/fbase.h0000644000175000017500000000113011004706610013261 0ustar apalapal/*****************************************************************************/ /* fbase.h */ /*****************************************************************************/ #ifndef __FBASE_H_INCLUDED #define __FBASE_H_INCLUDED 1 /*****************************************************************************/ int fbase_spline(double **fbase,int order,int n); int fbase_polynomial(double **fbase,int order,int n); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/statistics.c0000644000175000017500000000226011472571745014415 0ustar apalapal/*****************************************************************************/ /* statistics.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Standalone library for calculating median and mode of a data set. */ /* (c) 2001, 2004, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in statistics.h */ /*****************************************************************************/ #include #include #include #include #include "statistics.h" /*****************************************************************************/ static int median_compare(const void *px,const void *py) { if ( *(double *)px < *(double *)py ) return(-1); else return(1); } double median(double *data,int n) { double m; if ( data==NULL || n<=0 ) return(0.0); qsort((void *)data,n,sizeof(double),median_compare); if ( n%2 ) m=data[n/2]; else m=0.5*(data[n/2-1]+data[n/2]); return(m); } /*****************************************************************************/ fitsh-0.9.2/src/psf-base.c0000644000175000017500000000256510667340130013716 0ustar apalapal/*****************************************************************************/ /* psf-base.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to basic/common PSF handling. Actually, there is only */ /* one function here: psf_symmetrize()... */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include "psf.h" #include "psf-base.h" /*****************************************************************************/ int psf_symmetrize(psf *pdata) { double **parr,p,***psfstack; int i,j,w,nrd,nval; w=pdata->grid*(pdata->hsize*2+1); nval=(pdata->order+1)*(pdata->order+2)/2; psfstack=pdata->coeff; for ( nrd=nval ; nrd>0 ; nrd--,psfstack++ ) { parr=*psfstack; for ( i=0 ; i<(w+1)/2 ; i++ ) { for ( j=i ; j<(w+1)/2 ; j++ ) { p=parr[i][j]+parr[j][i]+ parr[w-1-i][j]+parr[w-1-j][i]+ parr[i][w-1-j]+parr[j][w-1-i]+ parr[w-1-i][w-1-j]+parr[w-1-j][w-1-i]; p=p/8.0; parr[i][j]=parr[j][i]= parr[w-1-i][j]=parr[w-1-j][i]= parr[i][w-1-j]=parr[j][w-1-i]= parr[w-1-i][w-1-j]=parr[w-1-j][w-1-i]=p; } } } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/fitsmask.h0000644000175000017500000001423411236250230014032 0ustar apalapal/*****************************************************************************/ /* fitsmask.h */ /*****************************************************************************/ #ifndef __FITS_XTN_H_INCLUDED #define __FITS_XTN_H_INCLUDED 1 /*****************************************************************************/ #include /*****************************************************************************/ /* fits_mask_read_from_header(): Creates a new mask using the header information (see 'MASKINFO' headers or any other optional headers can be set by 'hdr' if it is not NULL) of the FITS image 'img'. If 'sx' and 'sy' are valid sizes (thus, both of them are positive), the mask returned will have a size of 'sx' times 'sy', otherwise the size of the mask will be set using the appropriate fields of 'img'. If the creation of the mask fails (due to any reason, allocation error, or these size fields are invalid) the function returns NULL, otherwise it returns the pointer of the newly allocated mask (which can be free with fits_mask_free()). */ char ** fits_mask_read_from_header(fitsheaderset *header,int sx,int sy,char *hdr); /* fits_mask_mask_from_header(): Performs a logical 'and' operation between the mask 'mask' and the mask of the image 'img' (if there is any mask described by 'mh' or MASKINFO headers). The result is also stored in 'mask' (so the original mask 'mask' is going to be overwritten by the new one). If there's no mask information in 'img', the mask 'mask' is unchanged. */ int fits_mask_mask_from_header(char **mask,fitsheaderset *header,int sx,int sy,char *mh); int fits_mask_mask_line(char *line,fitsheaderset *header,int sx,int sy,int y0,char *maskhdr); int fits_mask_mask_more_line(char **lines,fitsheaderset *header,int sx,int sy,int y0,int ny,char *maskhdr); /* fits_mask_duplicate(): Duplicates the mask 'mask' (which has a size of 'sx' by 'sy'). If the duplication was not successful (usually due to insufficient memory), the function returns NULL, otherwise it returns the new mask. */ char ** fits_mask_duplicate(char **mask,int sx,int sy); /* fits_mask_export_as_header(): Compresses the mask 'mask' (which has a size of 'sx' times 'sy' or if these values are nonpositive, the size is derived using 'img') and stores it in the FITS header area of 'img'. The storage of the mask is almos human-readable (ascii numbers are stored), it's not so important to talk about the algorithm (which is quite primitive, see the source code for more). If the flag 'cl' is true, the function clears all mask information from the image 'img' before store the new mask. It's highly recommended to set 'cl' to true. If the function fails, it returns a nonzero value, otherwise it returns 0. If 'hdr' is not NULL, the header name specified by it is used, otherwise the default 'MASKINFO' header is set by the function. */ int fits_mask_export_as_header(fitsheaderset *header,int cl,char **mask,int sx,int sy,char *hdr); /* fits_mask_create_empty(): Creates an empty mask, with the size of 'sx' by 'sy' (if they are positive, otherwise the size if derived from 'img' if it is not NULL). The mask has all true values (actually filled with 1's). If the creation fails (due to any reason, allocation error, the 'sx'/'sy' values are invalid) the function returns NULL, otherwise it returns the pointer of the newly allocated mask (which can be freed with fits_mask_free()). */ char ** fits_mask_create_empty(int sx,int sy); /* fits_mask_expand_false(): Expands the false area in the mask 'mask' with a size of 'sx' by 'sy' with a border with a size of 'dis'. Note that the outbound area of the matrix 'cmin' is treated as a false area. The newly created matrix is returned. If NULL is returned, the allocation of the new matrix failed. The primarily usage of the function is to determine where can a point of an image be convolved with a given kernel. If the matrix 'cmin' contains the valid pixel mask of an image (with a size of 'sx' by 'sy') and 'dis' is the half-size of the kernel used for the convolution, the returned array contains the mask which has true elements where the convolution can be performed, so the kernel used doesn't intersect into any false pixel or into the outbound of the image. */ char ** fits_mask_expand_false(char **mask,int sx,int sy,int dis,int imv,int smv,int expand_border); /* fits_mask_and(), fits_mask_or(): Performs a logical 'and' or 'or' operation between the mask 'mask' and 'other' (both of them has a size of 'sx' by 'sy'). The result is stored in 'mask' (the original mask 'mask' is going to be overwritten). If 'other' is NULL (or its all elements are true), the mask 'mask' is unchanged. */ int fits_mask_and(char **mask,int sx,int sy,char **other); int fits_mask_or(char **mask,int sx,int sy,char **other); /* fits_mask_create_floyd(): Creates a Floyd-Steinberg dithered mask with the fill ratio of 'a'/'b'. The other mask creation parameters are like to fits_mask_create_empty(). */ char ** fits_mask_create_floyd(int sx,int sy,int a,int b,int smv); /* fits_mask_mask_nans(): Marks the pixels in the mask 'mask' where img->data is not a number (truly, ! isfinite()) with the flag 'setmask'. */ int fits_mask_mark_nans(fitsimage *img,char **mask,int setmask); /* fits_mask_trim(): Trims the mask 'mask' (with the original size of 'sx' times 'sy'). */ int fits_mask_trim(char ***mask,int sx,int sy,int x0,int y0,int nx,int ny,int outer); /* fits_mask_is_clean(): This function returns true (nonzero value) if all of the mask elements are zero, i.e. the mask/image is practically 'clean' from nasty pixels. */ int fits_mask_is_clean(char **mask,int sx,int sy); /* fits_mask_free(): Releases the memory are of 'mask' if it is not NULL. The function always return 0. */ int fits_mask_free(char **mask); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/imgtrans.h0000644000175000017500000000071411236250664014046 0ustar apalapal/*****************************************************************************/ /* imgtrans.h */ /*****************************************************************************/ #ifndef __IMGTRANS_H_INCLUDED #define __IMGTRANS_H_INCLUDED 1 #include int laplace_of_image(fitsimage *img); int laplace_of_image_ign(fitsimage *img); int cyclic_laplace_of_image(fitsimage *img); int cyclic_laplace_of_image_ign(fitsimage *img); #endif fitsh-0.9.2/src/weight-star.c0000644000175000017500000000574711236250470014461 0ustar apalapal/*****************************************************************************/ /* weight-star.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to weight stamp handling: */ /* create weight list from star list. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #include "tensor.h" #include "stars.h" #include "psf.h" #include "weight.h" /*****************************************************************************/ int weight_draw(weightlist *wl,star *stars,int nstar,int hsize,int grid,psf *tpd) { int o,l,n,order,fsize,ix0,iy0,i,j; double s,d,k,dflux,sum,zf,iz,gs,mom[MAX_DEVIATION_COEFF],*wmom,wz,x,y; star *ws; double ***zdata,**iarr,x0,y0; weight *ww; if ( stars==NULL || nstar<0 ) return(1); if ( grid<1 ) zf=1.0,grid=1; else zf=(double)grid; iz=1.0/zf; fsize=grid*(2*hsize+1); zdata=(double ***)tensor_alloc_3d(double,fsize,fsize,nstar); iarr=(double **)tensor_alloc_2d(double,fsize,fsize); wl->zdata=zdata; wl->weights=(weight *)malloc(sizeof(weight)*nstar); wl->nweight=nstar; wl->hsize=hsize; wl->grid=grid; for ( n=0 ; nflux; if ( dflux<=0.0 ) continue; x0=ws->location.gcx; y0=ws->location.gcy; ix0=(int)floor(x0), iy0=(int)floor(y0); x=(x0-ix0)+hsize; y=(y0-iy0)+hsize; if ( ws->shape.model==SHAPE_GAUSS || ws->shape.model==SHAPE_ELLIPTIC ) { s=ws->gsig; if ( ws->shape.model==SHAPE_ELLIPTIC ) d=ws->gdel,k=ws->gkap; else d=k=0; star_draw_gauss(iarr,fsize,fsize,x*zf,y*zf,s*zf,d*zf,k*zf); } else if ( ws->shape.model==SHAPE_DEVIATED ) { if ( grid>1 ) { wz=iz*iz; gs=ws->shape.gs*wz; order=ws->shape.order; for ( o=2,l=0 ; o<=order ; o++ ) { for ( j=0 ; j<=o ; j++,l++ ) { mom[l]=ws->shape.mom[l]*wz; } wz=wz*iz; } wmom=mom; } else { gs=ws->shape.gs; order=ws->shape.order; wmom=ws->shape.mom; } star_draw_deviated(iarr,fsize,fsize,x*zf,y*zf,gs,order,wmom); } else if ( ws->shape.model == SHAPE_PSF ) { star_draw_psf(iarr,fsize,fsize,x*zf,y*zf,tpd, ws->location.gcx,ws->location.gcy, ws->shape.gs*zf,ws->shape.gd*zf,ws->shape.gk*zf,ws->shape.gl*zf); } sum=0.0; for ( i=0 ; iweights[n]; ww->x=x0, ww->y=y0; ww->ix=ix0, ww->iy=iy0; ww->flux=dflux; ww->iarr=zdata[n]; } tensor_free(iarr); return(0); } /*****************************************************************************/ fitsh-0.9.2/src/weight-io.c0000644000175000017500000001235012771247743014121 0ustar apalapal/*****************************************************************************/ /* weight-io.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Functions related to weight stamp handling. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #include "fitsh.h" #include "tensor.h" #include "weight.h" /*****************************************************************************/ #define HDR_WGTDATA 0 #define HDR_WGTTABLE 1 #define HDR_WGTHSIZE 2 #define HDR_WGTSGRID 3 static char *wgthdr[]= { "WGTDATA", "WGTTABLE", "WGTHSIZE", "WGTSGRID", NULL }; /*****************************************************************************/ fits *weight_fits_create(weightlist *wl) { int fsize,hsize,grid,n; fits *img; fitsextension *fx; unsigned char *line; weight *ww; img=fits_create(); fits_set_standard(img,NULL); hsize=wl->hsize; grid =wl->grid; fsize=grid*(2*hsize+1); img->i.dim=3; img->i.sx=img->i.naxis[0]=fsize; img->i.sy=img->i.naxis[1]=fsize; img->i.naxis[2]=wl->nweight; img->i.vdata=wl->zdata; img->i.data =wl->zdata[0]; img->i.allocdata=NULL; img->i.bit=-32; img->i.curr.bscale=1.0,img->i.curr.bzero=0.0; img->i.read.bscale=1.0,img->i.read.bzero=0.0; fits_set_image_params(img); fits_set_extend(img,1,NULL); fits_set_header_boolean(img,wgthdr[HDR_WGTDATA],FITS_SH_FIRST,1,"Weight metadata is present as a BINTABLE, ..."); fits_set_header_integer(img,wgthdr[HDR_WGTTABLE],FITS_SH_FIRST,2,"... in sec [2] (1st extension after pri data)"); fits_set_header_integer(img,wgthdr[HDR_WGTHSIZE],FITS_SH_FIRST,hsize,"Half-size of the stamps"); fits_set_header_integer(img,wgthdr[HDR_WGTSGRID],FITS_SH_FIRST,grid,"Subpixel grid resolution of the stamps"); fx=fits_extension_new(img,FITS_EXT_BINTABLE); fits_bintable_create_fields(&fx->x.b,wl->nweight,5,FTF_SHORT,1,FTF_SHORT,1,FTF_FLOAT,1,FTF_FLOAT,1,FTF_FLOAT,1); fits_bintable_set_xtr_params(&fx->x.b,0,"IX" ,"pixel",NULL); fits_bintable_set_xtr_params(&fx->x.b,1,"IY" ,"pixel",NULL); fits_bintable_set_xtr_params(&fx->x.b,2,"X" ,"pixel",NULL); fits_bintable_set_xtr_params(&fx->x.b,3,"Y" ,"pixel",NULL); fits_bintable_set_xtr_params(&fx->x.b,4,"flux","adu" ,NULL); fits_bintable_alloc(&fx->x.b); fits_bintable_set_params(&fx->header,&fx->x.b); fits_headerset_set_string(&fx->header,"EXTNAME",FITS_SH_FIRST,"WEIGHTSTAMPS",NULL); for ( n=0 ; nnweight ; n++ ) { line=fx->x.b.data[n]; ww=&wl->weights[n]; *(short *)(line+fx->x.b.bfields[0].offset)=ww->ix; *(short *)(line+fx->x.b.bfields[1].offset)=ww->iy; *(float *)(line+fx->x.b.bfields[2].offset)=ww->x; *(float *)(line+fx->x.b.bfields[3].offset)=ww->y; *(float *)(line+fx->x.b.bfields[4].offset)=ww->flux; } return(img); } /*****************************************************************************/ int weight_parse_fits(fits *img,weightlist *wl) { fitsheader *hd; fitsextension *fx; fitsbtable *fb; fitsimage *fi; weight *ww; int i,k,l,hsize,grid,nweight,fsize; unsigned char *line; double ***zdata; if ( wl==NULL || img==NULL ) return(0); wl->zdata=NULL; wl->weights=NULL; wl->nweight=0; hd=fits_headerset_get_uniq_header(&img->header,wgthdr[HDR_WGTDATA]); if ( hd==NULL || hd->vtype != FITS_VBOOLEAN || ! hd->vint ) return(1); hd=fits_headerset_get_uniq_header(&img->header,wgthdr[HDR_WGTTABLE]); if ( hd==NULL || hd->vtype != FITS_VINT || hd->vint<2 ) return(2); i=hd->vint-2; if ( i>=img->nxtn ) return(3); fx=&img->xtns[i]; if ( fx->type != FITS_EXT_BINTABLE ) return(4); hd=fits_headerset_get_uniq_header(&img->header,wgthdr[HDR_WGTHSIZE]); if ( hd==NULL || hd->vtype != FITS_VINT || hd->vint<0 ) return(5); hsize=hd->vint; hd=fits_headerset_get_uniq_header(&img->header,wgthdr[HDR_WGTSGRID]); if ( hd==NULL || hd->vtype != FITS_VINT || hd->vint<=0 ) return(6); grid =hd->vint; fb=&fx->x.b; fi=&img->i; if ( fb->rowsize != 16 || fb->nrow<=0 ) return(7); i=fits_bintable_check_fields(fb,5,FTF_SHORT,1,FTF_SHORT,1,FTF_FLOAT,1,FTF_FLOAT,1,FTF_FLOAT,1); if ( i ) return(8); nweight=fb->nrow; fsize=grid*(2*hsize+1); if ( fi->dim != 3 || fi->vdata==NULL ) return(9); if ( fi->naxis[0] != fsize || fi->naxis[1] != fsize || fi->naxis[2] != nweight ) return(10); zdata=(double ***)fi->vdata; wl->zdata=(double ***)tensor_alloc_3d(double,fsize,fsize,nweight); wl->hsize=hsize; wl->grid =grid; wl->nweight=nweight; wl->weights=(weight *)malloc(sizeof(weight)*nweight); for ( i=0 ; iweights[i]; line=fb->data[i]; ww->ix =*(short *)(line+fb->bfields[0].offset); ww->iy =*(short *)(line+fb->bfields[1].offset); ww->x =*(float *)(line+fb->bfields[2].offset); ww->y =*(float *)(line+fb->bfields[3].offset); ww->flux=*(float *)(line+fb->bfields[4].offset); ww->iarr=wl->zdata[i]; for ( k=0 ; kiarr[k][l]=zdata[i][k][l]; } } } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/linear.c0000644000175000017500000000273411236252707013473 0ustar apalapal/*****************************************************************************/ /* linear.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Demonstartion and/or test module for `lfit` dynamic extensions. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2008; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include /*****************************************************************************/ /* these functions can be declared as static ones since the wrapper inside `lfit` reads only the exported `lfitfunction` arrays (here: "linear") */ static int function_line(double *vars,double *idvs,double *ret,double *diff); lfitfunction linear [] = { { "line", LFITFUNCTION_LINEAR, 2, 1, function_line }, { NULL, 0, 0, 0, NULL } }; /*****************************************************************************/ static int function_line(double *vars,double *idvs,double *ret,double *diff) { *ret = vars[0]*idvs[0]+vars[1]; if ( diff != NULL ) { diff[0]=idvs[0]; diff[1]=1.0; } /* *ret = vars[0]*vars[2]+vars[1]; if ( diff != NULL ) { diff[0]=vars[2]; diff[1]=1.0; diff[2]=vars[0]; } */ return(0); } /*****************************************************************************/ fitsh-0.9.2/src/fistar.c0000644000175000017500000010216112771247746013520 0ustar apalapal/*****************************************************************************/ /* fistar.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line tool for searching stars and get star parameters on an image.*/ /*****************************************************************************/ #define FITSH_FISTAR_VERSION "1.0rc5" /*****************************************************************************/ #include #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "fitsmask.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "math/fit/lmfit.h" #include "math/poly.h" #include "statistics.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "imgtrans.h" #include "tensor.h" #include "index/sort.h" #include "common.h" #include "magnitude.h" #include "stars.h" #include "psf.h" #include "psf-base.h" #include "psf-determine.h" #include "psf-io.h" #include "fistar.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_info(char *expr,...) { va_list ap; fprintf(stderr,"%s: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ #define ALG_PP 1 #define ALG_TRB 2 #define ALG_LNK 3 #define ALG_BIQ 4 #define COLL_REFINE_POSITION 1 /* 0x01 */ #define COLL_REFINE_SHAPE 2 /* 0x02 */ typedef struct { int niter; int refinelevel; double bhsize; } collectivefit; /* basic properties of star searching */ typedef struct /* and star model fitting... */ { int is_fit_model; int is_determine_psf; starfit sfp; starmodelfit smfs[16]; int nsmf; range srcrange; spatial imgbg; int algorithm; candidate *cands; int ncand; initcand *icands; int nicand; star *stars; int nstar; collectivefit cf; } starsearch; /*****************************************************************************/ int make_star_candidates(initcand *icands,int nicand,double rad, fitsimage *img,char **mask,candidate **rcands,int *rncand) { candidate *cands,*wc; int ncand,i,ix1,ix2,iy1,iy2,ix,iy,irad,k,l,t0,t1; int sx,sy; double dx,dy,rad2,dy2,f0; initcand *ic; ipoint *ipoints; int nipoint; starshape shp; if ( img==NULL || img->data==NULL ) return(-1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(-1); cands=NULL; ncand=0; irad=2+(int)rad; rad2=rad*rad; for ( i=0 ; ix); iy=(int)floor(ic->y); ix1=ix-irad,ix2=ix+irad; iy1=iy-irad,iy2=iy+irad; ipoints=(ipoint *)malloc(sizeof(ipoint)*((2*irad+1)*(2*irad+1))); nipoint=0, t0=t1=0; for ( k=iy1 ; k<=iy2 ; k++ ) { dy=(ic->y)-((double)k+0.5); dy2=dy*dy; for ( l=ix1 ; l<=ix2 ; l++ ) { dx=(ic->x)-((double)l+0.5); if ( dx*dx+dy2>rad2 ) continue; t0++; if ( k<0 || sy<=k ) continue; if ( l<0 || sx<=l ) continue; if ( mask != NULL && mask[k][l] ) continue; t1++; ipoints[nipoint].x=l, ipoints[nipoint].y=k; nipoint++; } } if ( nipoint==0 || t1ix=ix,wc->cx=ic->x, wc->iy=iy,wc->cy=ic->y; wc->bg=ic->bg; wc->sxx=ic->s+ic->d; wc->syy=ic->s-ic->d; wc->sxy=ic->k; shp.model=SHAPE_ELLIPTIC; shp.gs=ic->s, shp.gd=ic->d, shp.gk=ic->k; f0=star_get_unity_flux(&shp); if ( f0>0.0 ) wc->peak=wc->amp=ic->flux/f0; else wc->peak=wc->amp=0.0; wc->flux=ic->flux; wc->ipoints=ipoints; wc->nipoint=nipoint; wc->area=0.0; wc->flags=0; wc->marked=0; ncand++; } if ( rcands != NULL ) *rcands=cands; if ( rncand != NULL ) *rncand=ncand; return(0); } /*****************************************************************************/ int compare_x(int i,int j,void *p) { if ( ((star *)p)[i].location.gcx < ((star *)p)[j].location.gcx ) return(1); if ( ((star *)p)[i].location.gcx > ((star *)p)[j].location.gcx ) return(-1); return(0); } int compare_y(int i,int j,void *p) { if ( ((star *)p)[i].location.gcy < ((star *)p)[j].location.gcy ) return(1); if ( ((star *)p)[i].location.gcy > ((star *)p)[j].location.gcy ) return(-1); return(0); } int compare_peak(int i,int j,void *p) { if ( ((star *)p)[i].cand->peak < ((star *)p)[j].cand->peak ) return(1); if ( ((star *)p)[i].cand->peak > ((star *)p)[j].cand->peak ) return(-1); return(0); } int compare_fwhm(int i,int j,void *p) { if ( ((star *)p)[i].gfwhm < ((star *)p)[j].gfwhm ) return(1); if ( ((star *)p)[i].gfwhm > ((star *)p)[j].gfwhm ) return(-1); return(0); } int compare_amp(int i,int j,void *p) { if ( ((star *)p)[i].location.gamp < ((star *)p)[j].location.gamp ) return(1); if ( ((star *)p)[i].location.gamp > ((star *)p)[j].location.gamp ) return(-1); return(0); } int compare_flux(int i,int j,void *p) { if ( ((star *)p)[i].flux < ((star *)p)[j].flux ) return(1); if ( ((star *)p)[i].flux > ((star *)p)[j].flux ) return(-1); return(0); } int compare_noise(int i,int j,void *p) { if ( ((star *)p)[i].cand==NULL || ((star *)p)[j].cand==NULL ) return(0); if ( ((star *)p)[i].cand->noise < ((star *)p)[j].cand->noise ) return(1); if ( ((star *)p)[i].cand->noise > ((star *)p)[j].cand->noise ) return(-1); return(0); } int compare_sn(int i,int j,void *p) { double sn1,sn2; if ( ((star *)p)[i].cand==NULL || ((star *)p)[j].cand==NULL ) return(0); else if ( ((star *)p)[i].cand->noise<=0.0 || ((star *)p)[j].cand->noise<=0.0 ) return(0); else { sn1=((star *)p)[i].flux/((star *)p)[i].cand->noise; sn2=((star *)p)[j].flux/((star *)p)[j].cand->noise; if ( sn1sn2 ) return(-1); else return(0); } } /*****************************************************************************/ int fistar_determine_psf(fitsimage *img,char **mask,starsearch *ss,psfdetermine *pdparam,psf *tpd) { psfcandidate *pcands,*wc; int npcand,n,i,nipoint,ii,niter; star *ws; if ( is_verbose ) { i=pdparam->hsize*2+1; fprintf(stderr,"Determination of PSF [%dx%d]x(%dx%d), " "spatial order: %d ... ", i,i,pdparam->grid,pdparam->grid,pdparam->order); fflush(stderr); } npcand=ss->nstar; pcands=(psfcandidate *)malloc(sizeof(psfcandidate)*npcand); for ( n=0 ; nstars[n]; wc->nipoint=nipoint=ws->cand->nipoint; wc->ipoints=ws->cand->ipoints; wc->yvals=(double *)malloc(sizeof(double)*nipoint); memset(wc->yvals,0,sizeof(double)*nipoint); drawback_model(wc->ipoints,nipoint,wc->yvals, &ws->location,&ws->shape,+1.0); wc->bg =ws->location.gbg; wc->amp=ws->location.gamp; wc->cx =ws->location.gcx; wc->cy =ws->location.gcy; } niter=0; for ( ii=0 ; ii<=niter ; ii++ ) { psf_determine(img,mask,pcands,npcand,1,pdparam,tpd); psf_bgamp_fit(img,mask,pcands,npcand,1,tpd); if ( iiyvals,0,sizeof(double)*wc->nipoint); drawback_psf(wc->ipoints,wc->nipoint,wc->yvals, wc->cx,wc->cy,wc->amp,tpd,+1.0); } } } if ( is_verbose ) { fprintf(stderr,"done.\n"); } for ( n=0 ; nstars[n]; ws->psf.gcx=wc->cx, ws->psf.gcy=wc->cy; ws->psf.gamp=wc->amp; ws->psf.gbg =wc->bg ; } for ( n=npcand-1 ; n>=0 ; n-- ) { wc=&pcands[n]; if ( wc->yvals != NULL ) free(wc->yvals); } free(pcands); return(0); } /*****************************************************************************/ int fprint_fistar_usage(FILE *fw) { fprintf(fw, "Usage:\tfistar [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[[-i|--input][] [--frame ]] [-o|--output ]\n" "\t[-V|--verbose] [-C|-C|--comment]\n"); fprintf(fw, "General parameters:\n" "\t[--skynoise|-d ]\n" "\t[--[flux-]threshold|-t|-f ] [-p|--prominence ]\n" "\t[-s|--sort {x|y|peak|fwhm|amp|flux|noise|s/n}] [--mag-flux ,]\n" "\t[-M|--input-mask ] [--output-background ]\n" "\t[-r|--shrink ]\n" "\t[-F|--format ] [--section :,:]\n" "\t[--output-mark [--mark {dot|square|circle} --mark-size ]]\n"); fprintf(fw, "Format arguments (after --format, separated by commas):\n" "\t- id,ix,iy (ID, integer part of candidate coordinates)\n" "\t- cx,cy,cbg,camp,cmax,npix,cs,cd,ck (candidate parameters)\n" "\t- x,y,bg,amp,s,d,k,mom,l,sigma,delta,kappa,fwhm,ellip,pa,\n" "\t flux,noise,s/n,magnitude\n" "\t (star parameters: location, various shape parameters, and est'd flux)\n" "\t- px,py,pbg,pamp,ps,pd,pk,pl (PSF parameters)\n"); fprintf(fw, "Input star candidates (conflicts with candidate searching):\n" "\t[-C|--input-candidates [--col-xy <>,<>] [--col-shape <...>]]\n" "\t[-R|--candidate-radius ]\n"); fprintf(fw, "Input position list (also conflicts with candidate searching):\n" "\t[-P|--input-positions [--col-id <>] [--col-xy <>,<>]]\n" "\t[-g|--gain ]\n"); fprintf(fw, "Candidate search parameters (conflicts with candidates read from file):\n" "\t[--algorithm {parabolapeak|uplink}] [--only-candidates]\n" "Modelling and fit tuning parameters:\n" "\t[--model {gauss,elliptic,deviated[,order=]}\n" "\t [--iterations {symmetric=,general=}] ]\n" "\t[--collective-fit {iterations=,[position],[shape]|blockhalfsize=}]\n"); fprintf(fw, "Parameters of PSF determination:\n" "\t[--psf grid=,symmetrize,halfsize=,order=\n" "\t native[,spline]|integral[,kappa=]|circle[,~width=,~order=]]\n" "\t[--output-psf ]\n"); fprintf(fw, "Default parameters are:\n" "\t--algorithm uplink --model elliptic --iterations symmetric=4,general=2\n" "\t--threshold 100 --mark dot --mark-size 2 --mag-flux 10,10000\n"); return(0); } longhelp_entry fistar_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "-i, --input ", "Name of input file from which the sources are extracted." }, { "-o, --output ", "Name of the data file where the list of the extracted sources " "and their respective characteristics are written." }, { "Basic source detection and characterization options:", NULL }, { "-t, --threshold ", "Detection peak threshold, in ADUs." }, { "-f, --flux-threshold ", "Detection flux threshold, in ADUs." }, { "--algorithm ", "Source cadidate extraction algorithm. It can be \"uplink\" (default) " "or \"parabolapeak\"." }, { "-p, --prominence ", "Critical relative prominence parameter used in the \"uplink\" " "algorithm. The default is to use no prominence based pixel grouping." }, { "-r, --shrink ", "Shrink factor applied before star candidate detection. The image is " "shrunk by this specific factor and after the detection, the " "candidate coordinates are multiplied by this value." }, { "--only-candidates", "Do not involve any analitic model funcion during the derivation of " "the centroid coordinates and shape parameters, but derive these " "from some sort of simple pixel statistics." }, { "--model [order=]", "Analytic model function used in the second stage of source extraction. " "This can be \"gauss\" (symmetic Gaussian profile), \"elliptic\" " "(assymetric Gaussian profile) and \"deviated\" (Gaussian profile " "multiplied by a polynomial up to the specified order)." }, { "--iterations symmetric=,general=", "The number of Levenberg-Marquardt iterations during the analytic " "model fit. The fit is done in two substeps, first the symmetric " "profile parameters are derived only, which step is followed by " "the fit for all of the shape parameters. " }, { "-s, --sort {x|y|peak|fwhm|amp|flux|noise|s/n}", "Sort the output list of extracted sources by X or Y coordinate, " "peak flux (no background level subtracted), profile FWHM, peak " "intensity (background level is subtracted), total flux, noise level " "or signal-to-noise ratio; respectively. " }, { "--mag-flux ,", "Magnitude - flux conversion level. The specified magnitude will " "be equivalent to the specified flux level." }, { "-M, --input-mask ", "Input mask file to co-add to the mask of the input image. Useful for " "marking pixels to be excluded from source extraction process " "beyond the ones which are previously marked in the input image." }, { "-F, --format ", "Comma separated list of format tags, for formatting the " "output list of extracted sources. Each row represents an " "extracted source while the format specified here defines the " "quantities listed in each row of the output file. See \"Format " "tags\" for more details. " }, { "Format tags:", NULL }, { "id", "An unique identifier for the source (an integer number, in fact)." }, { "ix", "Integer X coordinate for the centroid pixel" }, { "iy", "Integer Y coordinate for the centroid pixel" }, { "x", "Centroid X coordinate in native coordinate convention." }, { "y", "Centroid Y coordinate in native coordinate convention." }, { "bg", "Background level" }, { "amp", "Peak amplitude" }, { "S", "Gaussian momenum for the stellar profile (S=1/sigma^2)" }, { "D", "plus-shaped momentum for the stellar profile" }, { "K", "cross-shaped momentum for the stellar profile" }, { "sigma", "sigma parameter for the stellar profile (FWHM is roughly 2.35 * sigma)" }, { "delta", "delta (plus-shaped deviance) parameter for the stellar profile" }, { "kappa", "kappa (cross-shaped deviance) parameter for the stellar profile" }, { "fwhm", "full width at half magnitude (FWHM) of the stellar profile" }, { "ellip", "ellipticity of the stellar profile" }, { "pa", "position angle of the stellar profile" }, { "flux", "Total flux of the source" }, { "nosie", "Noise level of the source" }, { "s/n", "Signal-to-noise ratio of the detection" }, { "magnitude", "Brightness of the source in magnitudes (see also --mag-flux)" }, { "cx", "Candidate centroid X coordinate (derived from pixel flux statistics)." }, { "cy", "Candidate centroid Y coordinate (derived from pixel flux statistics)." }, { "cbg", "Background level for the source candidate" }, { "camp", "Peak amplitude of the source candidate" }, { "cmax", "Maximum intensity on the source cadidate" }, { "cs", "Gaussian momenum for the source cadidate, derived from pixel flux statistics" }, { "cd", "plus-shaped momentum for the source cadidate, derived from pixel flux statistics" }, { "ck", "cross-shaped momentum for the source cadidate, derived from pixel flux statistics" }, { "npix", "number of pixels assigned to the detetcted source" }, { "Obtaining the point-spread function (PSF):", NULL }, { "--psf ", "Comma-separated list of parameters related to the PSF fitting:" }, { "grid=", "subgrid size for the PSF" }, { "halfsize=", "half-size of the PSF stamp, the full size of the stamp will always be " "2*+1 and the PSF itself is centered at the center of the " "central pixel." }, { "order=", "order of spatial variations in the PSF" }, { "symmetrize", "symmetrize the resulting PSF (i.e. fit a symmetric PSF instead of a normal one)" }, { "spline", "use a spline interpolation during the determination of the PSF" }, { "--output-psf ", "Name of the output file where the PSF is saved in FITS format. " "The PSF is stored in a 3 dimensional (a.k.a. \"data cube\") structure " "where the z-axis is for the various polynomial coefficients describing " "the spatially varied PSF. " }, { "Alternate sources for object candidates:", NULL }, { "-C, --input-cadidates ", __extension__ "Name of input cadidate list file. If such a file is defined in the " "command line, the cadidates are not searched by the build-in " "algorithms. Instead, the centroids are read from this file and the " "pixels for each object are defined within a certain radius from " "this centroid (see -r|--cadidate-radius also). The role of this " "option is twofold. First, it is suitable if only some of the " "sources have to be modelled with an analytic function; second, " "PSF determination can be done only a previously cleaned list of " "sources, in the case when there might be contaminating sources too." }, { "-r, --candidate-radius ", "This option defines a distance, where pixels within this are " "assigned to the candidate. " }, { "--col-xy ,", "Column indices for X and Y centroid coordinates. "}, { NULL, NULL } }; int fprint_fistar_long_help(FILE *fw,int is_wiki) { char *synopsis= "fistar [options] [-o|--output ]"; char *description= __extension__ "The main purpose of this program is to detect and extract sources (i.e. " "star-like objects) from astronomical images. The source detection and " "extraction are based on three major steps. First, pixel groups are derived " "which are possibly belong to the sources (these preliminary detections are " "callad source \"candidates\"). Second, these candidates are modelled with " "some sort of analytic model funcion, in order to derive more precise " "centroid coordinates and shape parameters. The last step is to extract the " "point-spread function (PSF) for the image, based on the detected and " "modelled sources. Basically, the input for this program must be an " "astronomical image while the output is the list of detected and extracted " "sources and their respective characteristics."; fprint_generic_long_help(fw,is_wiki,fistar_long_help,synopsis,description); return(0); } static char *default_format="id,ix,iy,cx,cy,cmax,x,y,b,a,fwhm,ellip,pa,s,d,k,flux"; int main(int argc,char *argv[]) { fits *img; char **mask; FILE *fr,*fw; int i,sx,sy,*indx; double skysigma,threshold,fluxthreshold,critical_prominence,candradius; int shrinkfactor; char *outname,*inimg,*markimgname,*areaimgname,*incandname,*inposname, *iterpar,*algpar,*modelpar,*psfoutname,*psfpar,*collfitpar; char **inmasklist,*formatpar,*basename; int sort,*oformat; int mark_symbol,mark_size; int is_help,frameno; colinfo col; starsearch ss; psf tpd; psfdetermine pdparam; magflux mf0; double gain; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; inimg=outname=NULL; skysigma=0.0; threshold=100.0;fluxthreshold=0.0; critical_prominence=0.0; ss.sfp.iter_symmetric=4; ss.sfp.iter_general=2; is_verbose=is_help=is_comment=0; markimgname=NULL;mark_symbol=MARK_SYM_DOTS;mark_size=2; psfoutname=psfpar=NULL; collfitpar=NULL; incandname=inposname=areaimgname=NULL;inmasklist=NULL;formatpar=NULL; frameno=-1; sort=-1; candradius=0.0; col.id=3; col.x=1,col.y=2; col.s=3,col.d=-1,col.k=-1; col.flux=-1,col.mag=-1,col.bg=-1; ss.srcrange.xmin=ss.srcrange.xmax=ss.srcrange.ymin=ss.srcrange.ymax=0; ss.is_fit_model=1; ss.is_determine_psf=0; ss.algorithm=ALG_LNK; /* default search method is the uplink algorithm */ ss.smfs[0].model=SHAPE_ELLIPTIC; /* default model is elliptical gaussian */ ss.smfs[0].order=2; ss.nsmf=1; algpar=modelpar=iterpar=NULL; ss.stars=NULL;ss.nstar=0; ss.cands=NULL;ss.ncand=0; ss.cf.niter=-1; ss.cf.refinelevel=0; ss.cf.bhsize=10.0; mf0.intensity=10000.0; mf0.magnitude=10.0; gain=1.0; shrinkfactor=1; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-i|--input:%s",&inimg, "--frame:%d",&frameno, "--section:%d:%d,%d:%d",&ss.srcrange.xmin,&ss.srcrange.xmax, &ss.srcrange.ymin,&ss.srcrange.ymax, "--algorithm:%s",&algpar, "-p|--prominence:%g",&critical_prominence, "--model:%s",&modelpar, "-r|--shrink:%d",&shrinkfactor, "-h|--help:%f",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-o|--output:%s",&outname, "-M|--input-mask:%t",&inmasklist, "-C|--input-candidates:%s",&incandname, "-P|--input-positions:%s",&inposname, "-R|--candidate-radius:%g",&candradius, /* equiv to 'hsize'... */ "--col-id:%Pd",&col.id, "--col-xy:%Pd,%Pd",&col.x,&col.y, "--col-gauss|--col-shape:%Pd",&col.s, "--col-elliptic|--col-shape-dev:%Pd,%Pd,%Pd",&col.s,&col.d,&col.k, "--col-flux:%Pd",&col.flux, "--col-bg:%Pd",&col.bg, "--col-mag:%Pd",&col.mag, "-d|--skysigma|--skynoise:%g",&skysigma, "-t|--threshold:%g",&threshold, "-f|--flux-threshold:%g",&fluxthreshold, "--only-candidates:%NS0f",&ss.is_fit_model, "--iterations:%s",&iterpar, "--collective-fit:%s",&collfitpar, "-s|--sort:%(x,y,peak,fwhm,amp,flux,noise,s/n)",&sort, "--mag-flux:%g,%g",&mf0.magnitude,&mf0.intensity, "-g|--gain:%g",&gain, "-F|--format:%s",&formatpar, "--output-marked|--mark-output:%s",&markimgname, "--mark=dot:%NS0f",&mark_symbol, "--mark=square:%NS1f",&mark_symbol, "--mark=circle:%NS2f",&mark_symbol, "--mark:%(dot,square,circle)",&mark_symbol, "--mark-size:%d",&mark_size, "--output-area:%s",&areaimgname, "--output-psf|--psf-output:%s",&psfoutname, "--psf:%f%s",&ss.is_determine_psf,&psfpar, "--comment:%i",&is_comment,"(C):%i",&is_comment, "--verbose:%i",&is_verbose,"(V):%i",&is_verbose, "-:%w",&inimg, "-*|+*:%e", "*:%w",&inimg, NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fistar",FITSH_FISTAR_VERSION,is_help); return(0); } else if ( 10 ) col.d--; if ( col.k>0 ) col.k--; if ( col.flux>0 ) col.flux--; if ( col.mag>0 ) col.mag--; if ( col.bg>0 ) col.bg--; if ( iterpar != NULL ) { ss.sfp.iter_general=0; i=scanpar(iterpar,SCANPAR_DEFAULT, "symmetric:%d",&ss.sfp.iter_symmetric, "general:%d",&ss.sfp.iter_general, NULL); if ( i ) { fprint_error("invalid fit iteration parameter '%s'",iterpar); return(1); } } if ( modelpar != NULL ) { int model,order,i,n,k; char *lmodelpar,*cmd[16]; lmodelpar=strdup(modelpar); n=tokenize_char(lmodelpar,cmd,'+',15); ss.nsmf=0; for ( i=0 ; iMAX_DEVIATION_ORDER ) order=MAX_DEVIATION_ORDER; ss.smfs[i].order=order; ss.nsmf++; } free(lmodelpar); } if ( algpar != NULL ) { if ( strcmp(algpar,"parabolapeak")==0 ) ss.algorithm=ALG_PP; else if ( strcmp(algpar,"triangulation")==0 ) ss.algorithm=ALG_TRB; else if ( strcmp(algpar,"uplink")==0 ) ss.algorithm=ALG_LNK; else if ( strcmp(algpar,"biquad")==0 ) ss.algorithm=ALG_BIQ; else { fprint_error("invalid star detection algorithm '%s'",algpar); return(1); } } if ( skysigma <= 0.0 && ss.algorithm==ALG_PP ) { fprint_error("unknown sky (background) sigma, it is required by the 'parabolapeak' algorithm"); return(1); } pdparam.hsize=4; pdparam.grid=4; pdparam.order=0; pdparam.type=PSF_DET_NATIVE; memset(&pdparam.param,0,sizeof(pdparam.param)); pdparam.is_symmetrize=0; if ( psfpar != NULL ) { i=scanpar(psfpar,SCANPAR_DEFAULT, "halfsize:%d",&pdparam.hsize, "grid:%d",&pdparam.grid, "order:%d",&pdparam.order, "native:" SNf(PSF_DET_NATIVE) ,&pdparam.type, "integral:"SNf(PSF_DET_INTEGRAL),&pdparam.type, "circle:" SNf(PSF_DET_CIRCLE) ,&pdparam.type, "spline|biquad:"SNf(PSF_DET_NATIVE)"%f" ,&pdparam.type,&pdparam.param.native.use_biquad, "kappa:" SNf(PSF_DET_INTEGRAL)"%g",&pdparam.type,&pdparam.param.integral.kappa, "circlewidth:" SNf(PSF_DET_CIRCLE)"%g" ,&pdparam.type,&pdparam.param.circle.width, "circleorder:" SNf(PSF_DET_CIRCLE)"%d" ,&pdparam.type,&pdparam.param.circle.order, "symmetrize:%f",&pdparam.type,&pdparam.is_symmetrize, NULL); if ( i ) { fprint_error("invalid PSF specification in '%s'",psfpar); return(1); } } if ( collfitpar != NULL ) { int niter; ss.cf.niter=0; niter=-1; i=scanpar(collfitpar,SCANPAR_DEFAULT, "iterations:%d",&niter, "position:%SN1f",&ss.cf.refinelevel, "shape:%SN2f",&ss.cf.refinelevel, "bhsize|blockhalfsize:%g",&ss.cf.bhsize, NULL); if ( i ) { fprint_error("invalid collective fit parameter in '%s'",collfitpar); return(1); } if ( niter>=0 ) ss.cf.niter=niter+1; } if ( formatpar != NULL ) oformat=output_format_stars(formatpar); else oformat=output_format_stars(default_format); if ( oformat==NULL ) { fprint_error("invalid format parameter '%s'",formatpar); return(1); } if ( inimg==NULL ) { fr=stdin;frameno=0; } else { basename=fits_basename(inimg,&frameno); if ( (fr=fopenread(basename))==NULL ) { fprint_error("unable to open input file '%s'.",basename); return(1); } } img=fits_read_frame_to_image(fr,frameno); fcloseread(fr); if ( img==NULL ) { fprint_error("unable to interpret input data as a FITS image."); return(1); } else if ( img->i.dim != 2 ) { fprint_error("image dimension is differ from 2."); return(1); } fits_rescale(img); sx=img->i.sx, sy=img->i.sy; mask=fits_mask_read_from_header(&img->header,sx,sy,NULL); if ( inmasklist != NULL ) { if ( join_masks_from_files(mask,sx,sy,inmasklist) ) { fprint_error("unable to read one of the input mask files"); return(1); } } fits_mask_mark_nans(&img->i,mask,MASK_NAN); if ( is_verbose ) fprintf(stderr,"[%dx%d]\n",sx,sy); if ( incandname != NULL && candradius <= 0.0 ) candradius=2.0; if ( incandname == NULL ) { range *sr; sr=&ss.srcrange; if ( sr->xmax<=sr->xmin || sr->ymax<=sr->ymin ) sr=NULL; switch ( ss.algorithm ) { /* parabolapeak */ case ALG_PP: determine_background(&img->i,&ss.imgbg,3,3,2); search_star_candidates(&img->i,mask,&ss.cands,&ss.ncand,sr,threshold,&ss.imgbg,skysigma); markout_candidates(&img->i,mask,ss.cands,ss.ncand); cleanup_candlist(&ss.cands,&ss.ncand); break; /* uplink */ case ALG_LNK: if ( fluxthreshold>0.0 ) /* use fluxthreshold instead */ threshold=0.0; search_star_candidates_link(&img->i,mask,&ss.cands,&ss.ncand,sr, threshold,fluxthreshold,critical_prominence); refine_candidate_params(&img->i,ss.cands,ss.ncand); break; /* triangulation-based */ /*case ALG_TRB: search_star_candidates_trb(img,mask,&ss.cands,&ss.ncand,sr,threshold); break;*/ default: fprint_error("desired candidate search algorihm has not been implemented yet."); return(1); break; } if ( is_verbose ) fprint_info("candidates (found): ncand=%d\n",ss.ncand); } else { FILE *fr; fr=fopenread(incandname); if ( fr==NULL ) { fprint_error("unable to open input list file '%s'",incandname); return(1); } read_star_candidates(fr,&col,&ss.icands,&ss.nicand,&mf0); if ( is_verbose ) fprint_info("candidates (read): nicand=%d\n",ss.nicand); make_star_candidates(ss.icands,ss.nicand,candradius,&img->i,mask,&ss.cands,&ss.ncand); fclose(fr); } if ( inposname != NULL ) { iposition *ips; int nip; FILE *fr,*fw; int **refarr; int x,y,i,j; double dx,dy; double magn,merr,flux,ferr; char *name; candidate *wc; fr=fopenread(inposname); if ( fr==NULL ) { fprint_error("unable to open input position list '%s'",inposname); return(1); } read_input_position_list(fr,&col,&ips,&nip); fcloseread(fr); refarr=(int **)tensor_alloc_2d(int,sx,sy); for ( i=0 ; i=sx || y<0 || y>=sy || ( mask != NULL && mask[y][x] ) || refarr[y][x]<0 ) { wc=NULL; flux=ferr=0.0; } else { wc=&ss.cands[refarr[y][x]]; flux=wc->flux; if ( flux<=0.0 ) flux=ferr=0.0; else ferr=sqrt(flux/gain+wc->noise*wc->nipoint); } if ( flux>0.0 ) { flux_to_mag_magerr(flux,ferr,&mf0,&magn,&merr); fprintf(fw,"%20s %10.3f %10.3f G--- %8.4f %8.4f\n",name,dx,dy,magn,merr); } else { fprintf(fw,"%20s %10.3f %10.3f X--- %8s %8s\n",name,dx,dy,"-","-"); } } fcloseread(fw); fits_free(img); return(0); } if ( ss.cf.niter<0 ) { if ( ss.is_fit_model ) { ss.sfp.fit_flags=FIT_XY|FIT_AB|FIT_WIDTH|FIT_DEVIATION; fit_star_single_model(&img->i,mask,ss.cands,ss.ncand,&ss.stars,&ss.nstar,&ss.sfp,ss.smfs[0].model,ss.smfs[0].order); if ( is_verbose ) fprintf(stderr,"nstar=%d\n",ss.nstar); } } else { ipointlist *ipls; int nstar,n; convert_candidates(ss.cands,ss.ncand,&ss.stars,&ss.nstar); nstar=ss.nstar; ipls=(ipointlist *)malloc(sizeof(ipointlist)*nstar); for ( n=0 ; n0 ) { collective_fit_star_single_model_iterative(&img->i,mask, ss.stars,nstar,ipls,&ss.sfp,ss.cf.refinelevel,ss.cf.niter-1); } else { collective_fit_star_single_model_blocked(&img->i,mask, ss.stars,nstar,ipls,ss.cf.bhsize); } cleanup_starlist(&ss.stars,&ss.nstar); free(ipls); } if ( ss.is_determine_psf ) { fistar_determine_psf(&img->i,mask,&ss,&pdparam,&tpd); } if ( ss.stars==NULL ) { convert_candidates(ss.cands,ss.ncand,&ss.stars,&ss.nstar); } if ( ss.nstar>0 ) { indx=(int *)malloc(sizeof(int)*ss.nstar); for ( i=0 ; ii,ss.stars,ss.nstar,mark_symbol,mark_size); fits_write(fw,img); fclosewrite(fw); } } if ( areaimgname != NULL ) { FILE *fw; fw=fopenwrite(areaimgname); if ( fw != NULL ) { int i,j,ix,iy; for ( i=0 ; inipoint ; j++ ) { ix=ss.stars[i].cand->ipoints[j].x, iy=ss.stars[i].cand->ipoints[j].y; img->i.data[iy][ix]=0.0; } } fits_write(fw,img); fclosewrite(fw); } } fits_free(img); return(0); } /*****************************************************************************/ /* development branch, star finding based on biquad surfaces */ /* search_star_candidates_biquad(img,mask,&stars,&nstar); if ( is_verbose ) fprintf(stderr,"nstar0=%d\n",nstar); */ /* to be continued soon... */ fitsh-0.9.2/src/firandom.c0000644000175000017500000012756412771573333014037 0ustar apalapal/*****************************************************************************/ /* firandom.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line utility to create artificial images. */ /*****************************************************************************/ #define FITSH_FIRANDOM_VERSION "1.4.0" /*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "math/point.h" #include "tensor.h" #include "common.h" #include "stars.h" #include "psf.h" #include "psf-io.h" #include "weight.h" #include "magnitude.h" #include "history.h" #include "fitsmask.h" #include "maskdraw.h" #include "firandom.h" #define FIRANDOM_DEFAULT_NOISE_SUPPRESSION 10000.0 #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ /* gain: fotons/adu, usually > 1... */ int draw_star_montecarlo_gauss(fitsimage *img,stargenparam *sgp,double x0,double y0,double dflux,double is,double id,double ik) { int sx,sy,ix,iy,subx,suby,flux; double x,y,fadu; if ( img==NULL ) return(-1); if ( img->data==NULL ) return(-1); sx=img->sx,sy=img->sy; if ( sgp->is_intinelect ) flux=(int)dflux; else flux=(int)(dflux*sgp->gain+0.5); if ( flux<=0 ) return(1); fadu=1.0/sgp->gain; if ( sgp->subpixeldata==NULL || sgp->subg==0 ) { for ( ; flux>0 ; flux-- ) { get_gaussian_2d(x0,y0,is,id,ik,&x,&y); ix=(int)floor(x), iy=(int)floor(y); if ( ix<0 || iy<0 || ix>=sx || iy>=sy ) continue; img->data[iy][ix]+=fadu; } } else { for ( ; flux>0 ; flux-- ) { get_gaussian_2d(x0,y0,is,id,ik,&x,&y); ix=(int)floor(x), iy=(int)floor(y); if ( ix<0 || iy<0 || ix>=sx || iy>=sy ) continue; subx=(int)((x-(double)ix+2)*(double)sgp->subg)%sgp->subg; suby=(int)((y-(double)iy+2)*(double)sgp->subg)%sgp->subg; img->data[iy][ix]+=sgp->subpixeldata[suby][subx]*fadu; } } return(0); } int draw_star_from_array(fitsimage *img,int ix0,int iy0,double **iarr,int hsize,int sg,double dflux,double **subpix,double gain) { int i,j,k,l,fsize,is_subgrid,sx,sy,si,sj,is_photnoise; double sum,w,sw; fsize=(2*hsize+1)*sg; if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); sum=0.0; for ( i=0 ; i1 && subpix!=NULL ) is_subgrid=1; else is_subgrid=0; if ( gain > 0.0 ) is_photnoise=1; else is_photnoise=0; for ( i=iy0-hsize,si=0 ; i<=iy0+hsize ; i++,si+=sg ) { if ( i<0 || i>=sy ) continue; for ( j=ix0-hsize,sj=0 ; j<=ix0+hsize ; j++,sj+=sg ) { if ( j<0 || j>=sx ) continue; if ( ! is_subgrid ) w=iarr[si][sj]; else { w=0.0; for ( k=0 ; k0.0 ) w=get_gaussian(w,sqrt(w/gain)); if ( w<=0.0 ) continue; img->data[i][j]+=w; } } return(0); } int draw_star_integral_gauss(fitsimage *img,stargenparam *sgp,double x0,double y0,double dflux,double is,double id,double ik) { int hsize,grid,ix0,iy0,fsize; double vgain,dgrid; static double **iarr=NULL; static int afsize=0; if ( img==NULL || img->data==NULL ) return(-1); if ( sgp->is_intinelect ) dflux/=sgp->gain; if ( sgp->is_photnoise ) vgain=sgp->gain; else vgain=0.0; if ( dflux*sgp->gain<=0.0 ) return(0); hsize=(int)(is*sqrt(2.0*log(dflux*sgp->gain*sgp->nsuppress/(is*is)))+1.0); if ( hsize>1023 ) hsize=1023; /* extraordinary... */ if ( sgp->subpixeldata==NULL || sgp->subg<=0 ) grid=1; else grid=sgp->subg; dgrid=(double)grid; fsize=(2*hsize+1)*grid; if ( fsize>afsize ) { afsize=fsize; if ( iarr != NULL ) tensor_free(iarr); iarr=(double **)tensor_alloc_2d(double,afsize,afsize); } ix0=(int)floor(x0),x0-=(double)ix0, iy0=(int)floor(y0),y0-=(double)iy0; star_draw_gauss(iarr,fsize,fsize,(x0+hsize)*dgrid,(y0+hsize)*dgrid, is*dgrid,id*dgrid,ik*dgrid); draw_star_from_array(img,ix0,iy0,iarr,hsize,grid,dflux,sgp->subpixeldata,vgain); return(0); } int draw_star_integral_deviated(fitsimage *img,stargenparam *sgp,double x0,double y0,double dflux,double gs,int order,double *mom) { int hsize,grid,ix0,iy0,fsize; double vgain,dgrid; static double **iarr=NULL; static int afsize=0; double cgs,gmom[MAX_DEVIATION_COEFF],*cmom; if ( img==NULL || img->data==NULL ) return(-1); if ( sgp->is_intinelect ) dflux/=sgp->gain; if ( sgp->is_photnoise ) vgain=sgp->gain; else vgain=0.0; if ( dflux*sgp->gain<=0.0 ) return(0); if ( gs<=0.0 ) return(0); ix0=(int)floor(x0),x0-=(double)ix0, iy0=(int)floor(y0),y0-=(double)iy0; hsize=(int)(sqrt(2.0*log(gs*dflux*sgp->gain*sgp->nsuppress)/gs)+1.0); if ( sgp->subpixeldata==NULL || sgp->subg<=0 ) grid=1; else grid=sgp->subg; fsize=(2*hsize+1)*grid; dgrid=(double)grid; if ( fsize>afsize ) { afsize=fsize; if ( iarr != NULL ) tensor_free(iarr); iarr =(double **)tensor_alloc_2d(double,afsize,afsize); } if ( grid>1 ) { double igrid,w; int o,l,j; igrid=1.0/dgrid; w=igrid*igrid; cgs=w*gs; for ( o=2,l=0 ; o<=order ; o++ ) { for ( j=0 ; j<=o ; j++,l++ ) { gmom[l]=mom[l]*w; w=w*igrid; } } cmom=gmom; } else { cgs =gs; cmom=mom; } star_draw_deviated(iarr,fsize,fsize,(x0+hsize)*dgrid,(y0+hsize)*dgrid,cgs,order,cmom); draw_star_from_array(img,ix0,iy0,iarr,hsize,grid,dflux,sgp->subpixeldata,vgain); return(0); } int draw_star_integral_psf(fitsimage *img,stargenparam *sgp,double x0,double y0, double px,double py, double is,double id,double ik,double il,double dflux) { static double **iarr=NULL; static int afsize=0; int hsize,fsize; int ix0,iy0,grid; double vgain,dgrid; double det,nrm; psf *p; if ( img==NULL || img->data==NULL ) return(-1); if ( sgp->is_intinelect ) dflux/=sgp->gain; if ( sgp->is_photnoise ) vgain=sgp->gain; else vgain=0.0; if ( dflux*sgp->gain<=0.0 ) return(0); det=is*is+il*il-id*id-ik*ik; if ( is<=0.0 && det<=0.0 ) nrm=1.0; else nrm=sqrt(is*is+il*il+id*id+ik*ik); ix0=(int)floor(x0),x0-=(double)ix0, iy0=(int)floor(y0),y0-=(double)iy0; if ( sgp->subpixeldata==NULL || sgp->subg<=0 ) grid=1; else grid=sgp->subg; p=sgp->tpd; if ( p==NULL ) return(1); hsize=(int)(nrm*(double)(p->hsize+2)); fsize=grid*(2*hsize+1); dgrid=(double)grid; if ( fsize>afsize ) { if ( iarr != NULL ) tensor_free(iarr); iarr =(double **)tensor_alloc_2d(double,fsize,fsize); afsize=fsize; } star_draw_psf(iarr,fsize,fsize,(x0+hsize)*dgrid,(y0+hsize)*dgrid,p,px,py, is*dgrid,id*dgrid,ik*dgrid,il*dgrid); draw_star_from_array(img,ix0,iy0,iarr,hsize,grid,dflux,sgp->subpixeldata,vgain); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int draw_starlist(fitsimage *img,stargenparam *sgp,star *stars,int nstar,int zoom) { int o,j,l,n,order; double s,d,k,dflux,zf,iz,gs,mom[MAX_DEVIATION_COEFF],*wmom,wz; star *ws; if ( zoom<1 ) zf=1.0,zoom=1; else zf=(double)zoom; iz=1.0/(double)zoom; for ( n=0 ; nflux; if ( dflux<=0.0 ) continue; if ( ws->shape.model==SHAPE_GAUSS || ws->shape.model==SHAPE_ELLIPTIC ) { s=ws->gsig; if ( ws->shape.model==SHAPE_ELLIPTIC ) d=ws->gdel,k=ws->gkap; else d=k=0; if ( ! sgp->method ) { if ( sgp->is_photnoise ) dflux=get_gaussian(dflux,sqrt(dflux/sgp->gain)); draw_star_montecarlo_gauss(img,sgp,ws->location.gcx*zf,ws->location.gcy*zf,dflux,s*zf,d*zf,k*zf); } else draw_star_integral_gauss(img,sgp,ws->location.gcx*zf,ws->location.gcy*zf,dflux,s*zf,d*zf,k*zf); } else if ( ws->shape.model==SHAPE_DEVIATED ) { if ( zoom>1 ) { wz=iz*iz; gs=ws->shape.gs*wz; order=ws->shape.order; for ( o=2,l=0 ; o<=order ; o++ ) { for ( j=0 ; j<=o ; j++,l++ ) { mom[l]=ws->shape.mom[l]*wz; } wz=wz*iz; } wmom=mom; } else { gs=ws->shape.gs; order=ws->shape.order; wmom=ws->shape.mom; } draw_star_integral_deviated(img,sgp,ws->location.gcx*zf,ws->location.gcy*zf,dflux,gs,order,wmom); } else if ( ws->shape.model==SHAPE_PSF ) { draw_star_integral_psf(img,sgp,ws->location.gcx*zf,ws->location.gcy*zf, ws->location.gcx,ws->location.gcy, ws->shape.gs*zf,ws->shape.gd*zf,ws->shape.gk*zf,ws->shape.gl*zf,dflux); } } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int quantize_image(fitsimage *img) { int i,j,sx,sy; if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); for ( i=0 ; idata[i][j]=floor(img->data[i][j]); } } return(0); } int divide_image(fitsimage *img,double d) { int i,j,sx,sy; if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); if ( d<=0.0 ) return(1); d=1.0/d; for ( i=0 ; idata[i][j]=d*img->data[i][j]; } } return(0); } /*****************************************************************************/ int read_subpixel_file(FILE *fr,double ***rsubpixeldata,int *rsubg) { double **subpixeldata,x,y,v; int subg,n,i,j,ix,iy; char buff[256],*cmd[4]; point *points; int npoint; points=NULL;npoint=0; while ( ! feof(fr) ) { if ( fgets(buff,255,fr)==NULL ) break; remove_newlines_and_comments(buff); n=tokenize_spaces(buff,cmd,3); if ( n<3 ) continue; ix=iy=-1; sscanf(cmd[0],"%lg",&x);ix=(int)floor(x); sscanf(cmd[1],"%lg",&y);iy=(int)floor(y); if ( ! isfinite(x) || ! isfinite(y) ) continue; if ( ix<0 || iy<0 ) continue; sscanf(cmd[2],"%lg",&v); if ( ! isfinite(v) ) continue; points=(point *)realloc(points,sizeof(point)*(npoint+1)); points[npoint].x=(double)ix, points[npoint].y=(double)iy; points[npoint].value=v; npoint++; }; subg=0; for ( i=0 ; isubg ) subg=ix; if ( iy>subg ) subg=iy; } subg++; subpixeldata=tensor_alloc_2d(double,subg,subg); for ( i=0 ; icolx>maxcol ) maxcol=ilp->colx; if ( ilp->coly>maxcol ) maxcol=ilp->coly; if ( ilp->colmag>maxcol ) maxcol=ilp->colmag; if ( ilp->colflux>maxcol ) maxcol=ilp->colflux; switch ( ilp->listtype ) { case LISTTYPE_FEP: case LISTTYPE_SIG: case LISTTYPE_SDK: /* 3 sh.cols */ if ( ilp->colsh1>maxcol ) maxcol=ilp->colsh1; if ( ilp->colsh2>maxcol ) maxcol=ilp->colsh2; if ( ilp->colsh3>maxcol ) maxcol=ilp->colsh3; break; case LISTTYPE_SMM: /* 2 sh.cols */ if ( ilp->colsh1>maxcol ) maxcol=ilp->colsh1; if ( ilp->colsh2>maxcol ) maxcol=ilp->colsh2; break; case LISTTYPE_PDS: /* 4 sh.cols */ if ( ilp->colsh1>maxcol ) maxcol=ilp->colsh1; if ( ilp->colsh2>maxcol ) maxcol=ilp->colsh2; if ( ilp->colsh3>maxcol ) maxcol=ilp->colsh3; if ( ilp->colsh4>maxcol ) maxcol=ilp->colsh4; break; case LISTTYPE_PSF: /* no sh.cols*/ break; default: break; } maxcol++; if ( maxcol>MAX_COL ) cmd=cmd_dynamic=(char **)malloc(sizeof(char *)*(maxcol+1)); else cmd=cmd_static,cmd_dynamic=NULL; stars=NULL;nstar=0; while ( ! feof(fr) ) { rbuff=freadline(fr); if ( rbuff==NULL ) break; remove_newlines_and_comments(rbuff); n=tokenize_spaces(rbuff,cmd,maxcol); if ( ncolx ],"%lg",&cx); i+=sscanf(cmd[ilp->coly ],"%lg",&cy); if ( ilp->colflux>=0 ) { i+=sscanf(cmd[ilp->colflux],"%lg",&cf); } else if ( ilp->colmag>=0 ) { i+=sscanf(cmd[ilp->colmag],"%lg",&cf); cf=mag_to_flux(cf,&ilp->mf0); } if ( i<3 || ! ( isfinite(cx) && isfinite(cy) && isfinite(cf) ) ) continue; switch ( ilp->listtype ) { case LISTTYPE_FEP: case LISTTYPE_SIG: case LISTTYPE_SDK: gs=gd=gk=gl=0.0;order=0; /*** fep, sdk or SDK ****/ i =sscanf(cmd[ilp->colsh1],"%lg",&m1); i+=sscanf(cmd[ilp->colsh2],"%lg",&m2); i+=sscanf(cmd[ilp->colsh3],"%lg",&m3); if ( i<3 || ! ( isfinite(m1) && isfinite(m2) && isfinite(m3) ) ) continue; switch ( ilp->listtype ) { case LISTTYPE_FEP: fep_to_sdk(m1,m2,m3,&s,&d,&k);break; case LISTTYPE_SIG: s=m1;d=m2;k=m3;break; case LISTTYPE_SDK: isdk_to_sdk(m1,m2,m3,&s,&d,&k);break; default: s=m1;d=m2;k=m3;break; } model=SHAPE_ELLIPTIC; break; case LISTTYPE_SMM: s=d=k=0.0; /*** Smom ***************/ i=sscanf(cmd[ilp->colsh1],"%lg",&gs); if ( i<1 || ! ( isfinite(gs) || gs<=0.0 ) ) continue; i=sscanf(cmd[ilp->colsh2],"%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg", &mom[0],&mom[1],&mom[2],&mom[3],&mom[4],&mom[5],&mom[6], &mom[7],&mom[8],&mom[9],&mom[10],&mom[11]); if ( i==12 ) order=4; else if ( i>=7 ) order=3; else if ( i>=3 ) order=2; else continue; model=SHAPE_DEVIATED; gd=gk=gl=0.0; break; case LISTTYPE_PSF: s=d=k=0.0; gs=1.0;gd=gk=gl=0.0; model=SHAPE_PSF; order=0; break; case LISTTYPE_PDS: s=d=k=0.0; i =sscanf(cmd[ilp->colsh1],"%lg",&gs); i+=sscanf(cmd[ilp->colsh2],"%lg",&gd); i+=sscanf(cmd[ilp->colsh3],"%lg",&gk); i+=sscanf(cmd[ilp->colsh4],"%lg",&gl); if ( i<4 || ! ( isfinite(gs) && isfinite(gd) && isfinite(gk) && isfinite(gl) ) ) continue; model=SHAPE_PSF; order=0; break; default: model=0; order=0; break; } if ( ! model ) continue; stars=(star *)realloc(stars,sizeof(star)*(nstar+1)); ws=&stars[nstar]; ws->location.gcx=cx, ws->location.gcy=cy, ws->flux=cf; ws->gsig=s; ws->gdel=d; ws->gkap=k; ws->shape.model=model; ws->shape.order=order; ws->shape.gs=gs; ws->shape.gd=gd; ws->shape.gk=gk; ws->shape.gl=gl; for ( i=0 ; i<(order+1)*(order+2)/2-3 ; i++ ) { ws->shape.mom[i]=mom[i]; } for ( ; ishape.mom[i]=0.0; } nstar++; }; *rstars=stars; *rnstar=nstar; if ( cmd_dynamic != NULL ) free(cmd_dynamic); return(0); } int write_output_list(FILE *fw,star *stars,int nstar,int listtype,magflux *mf) { int i; double s,d,k,m1,m2,m3; if ( is_comment ) { fprintf(fw,"# Star list, dumped by firandom.\n"); if ( mf==NULL ) fprintf(fw,"# X Y FLUX "); else fprintf(fw,"# X Y Magnitude"); if ( listtype==LISTTYPE_FEP ) fprintf(fw," FWHM Ellipt. PosAng. (--fep)"); else if ( listtype==LISTTYPE_SIG ) fprintf(fw," sigma delta kappa (--sdk)"); else if ( listtype==LISTTYPE_SDK ) fprintf(fw," S D K (--SDK)"); fprintf(fw," IdNum\n"); } for ( i=0 ; i] [-C|--comment] [-V|--verbose]\n"); fprintf(fw, "Common modelling parameters:\n" "\t[-g|--gain ] [-m \"\"] [-d ]\n" "\t[--photon-noise|--no-photon-noise] [-U [--normalize]]\n" "Output image size and data format parameters:\n" "\t[-s|--size ,] [-b|--bitpix ]\n" "\t[-D|--data bitpix=,bscale=,bzero=|]\n"); fprintf(fw, "Creating background and/or full image from textual input:\n" "\t[-S|--input-sky|--input-background ]\n" "\t[--col-pixel ,] [--col-value ]\n"); fprintf(fw, "Input specification:\n" "\t[-L|--input-list |-l|--list \"\"]\n" "\t[--output-list ]\n" "\t[--{fep|sdk|SDK|Smom|psf|psfdst}{|-input|-output}]\n" "\t[--col-xy ,]\n" "\t[--col-flux |--col-mag ]\n" "\t[--col-shape ,,[,<>]]\n"); fprintf(fw, "Input PSF specification:\n" "\t[-P|--input-psf ]\n"); fprintf(fw, "Fine-tuning of modelling:\n" "\t[--seed {|auto}] [--seed-{noise|spatial|photon} {|auto}]\n" "\t[--mag-flux ,]\n" "\t[--[no-]monte-carlo|--[no-]integral [--noise-suppression ]]\n" "\t[--[no-]quantize] [--[no-]adus|--[no-]electrons]\n"); fprintf(fw, "Handling masks:\n" "\t[-q|--mask-block :,[:,]] [--mask-block ...]\n" "\t[--output-mask \n"); fprintf(fw, "Weight output generation:\n" "\t[--output-weight [-w|--weight hsize=,zoom=]]\n"); fprintf(fw, "Default parameters:\n" "\t-s 256,256 -m 0 -d 0 -b -32 --mag-flux 10,10000 --adus --no-quantize\n" "\t--gain 1.0 --no-photon-noise --integrate --noise-suppression %g\n" "\t--seed 0 --col-xy 1,2 --col-flux 3 --col-shape 4,5,6\n",FIRANDOM_DEFAULT_NOISE_SUPPRESSION); fprintf(fw, "Format of : \n" "\t[f=],[e=],[p=],\n" "\t[s=],[d=],[k=],[S=],[D=],[K=],\n" "\t*[{x|X}=,{y|Y}=,{m=|i=},[{f,e,p|s,d,k|S,D,K}=...]],\n" "\t[f,e,p=...],[s,d,k=...],[S,D,K=...],*[...],...\n"); return(0); } longhelp_entry firandom_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help, --help-long", "Gives a detailed list of command line options." }, { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki", "Gives a detailed list of command line options in Mediawiki format." }, { "--version, --version-short, --short-version", "Gives some version information about the program." }, { "Creating artificial object lists:", NULL }, { "-l, --list ", "Specifications for object list. The \"list\" parameter should be a " "set of comma separated tags, which can either be a value declaration " "or a repeat count followed by an expression between square brackets " "giving specifications for individual objects to be added to the list, " "also in the form of value declaration. The value declaration " "has the sintax of =, where the variables can be the " "following: " }, { "f", "full width at half magnitude (FWHM) of the stellar " "profiles to be created" }, { "e", "ellipticity of the stellar profiles" }, { "p", "position angle of the stellar profiles" }, { "s", "sigma parameter for the stellar profile (FWHM is roughly 2.35 * sigma)" }, { "d", "delta (plus-shaped deviance) parameter for the stellar profile" }, { "k", "kappa (cross-shaped deviance) parameter for the stellar profile" }, { "S", "Gaussian momenum (a.k.a. profile sharpness parameter) for the stellar profile (S=1/sigma^2)" }, { "D", "plus-shaped momentum for the stellar profile" }, { "K", "cross-shaped momentum for the stellar profile" }, { "x", "normalized X coordinate of the profile centroid (using the standard normalization)" }, { "X", "absolute X coordinate of the profile centroid" }, { "y", "normalized y coordinate of the profile centroid (using the standard normalization)" }, { "Y", "absolute Y coordinate of the profile centroid" }, { "m", "magnitude of the stellar object" }, { "i", "flux of the stellar object" }, { __extension__ "One can use only one of the three equivalent set of profile shape " "parameters (i.e. f/e/p, s/d/k or S/D/K). See some more detailed documentation " "about these parameters. In the expressions which are in the square brackets, " "one can use arbitrary arithmetic expressions, using the standard basic " "arithmetical operators, elementary functions and the functions r(lo,hi) " "and g(mean,sigma) which results an uniformly distrbuted random number " "between \"lo\" and \"hi\" and a Gaussian random number with the specified " "\"mean\" and \"sigma\" (standard deviation), respectively. " "In the expressions for magnitude or intensity, one can use the previously " "defined values for the centroid coordinates too. The variable \"n\" is " "increased between 0 and the repeat count during the evaluation of the " "square bracket expressions. ", NULL }, { "", NULL }, { "--output-list ", "Name of the list file where the object list created by the subsequent " "--list options are saved. " }, { "--fep, --fep-output", "Save the shape parameters as FWHM, ellipticity and position angle to " "the output list file." }, { "--sdk, --sdk-output", "Save the shape parameters as sigma, delta and kappa to " "the output list file." }, { "--SDK, --SDK-output", "Save the shape parameters as Gaussian momenta to " "the output list file." }, { "Creating artificial images:", NULL }, { "-s, --size ,", "Size of the image to be created." }, { "-b, --bitpix ", "Standard FITS output bitpix value." }, { "-D, --data ", "Output pixel data format specification." }, { "-m, --sky ", "Sky (background level) for the image. This can be either a constant " "or an arbitrary function of the x, y, X and Y coordinates (see above) " "for a backgroud with shows systematic variations. One can use the " "previously discussed r(lo,hi) and g(mean,sigma) functions, in order " "to add some sort of noise to the background. " }, { "-d, --sky-noise ", "Additional Gaussian noise, equivalent to the term \"+g(,0)\" " "added after the background level expression. " }, { "--photon-noise, --no-photon-noise", "Emulate or disable the effect of photon noise on the individual " "stellar objects." }, { "-l, --list ", "Specifications for object list (see above)." }, { "-L, --input-list ", "Name of the input list file from which the coordinates, shape " "parameters and intensities are read for the individual objects. " }, { "--col-xy ,", "Column indices for X and Y (absolute) centroid coordinates. "}, { "--col-flux ", "Column index for flux (intensity)." }, { "--col-mag ", "Column index for astronomical magnitude, see also --mag-flux." }, { "--col-shape ,[,]", "Column indices for stellar profile parameters. Either 1 or 3 columns " "should be specified following this command line switch. One shape parameter " "is interpreted as a profile size parameter where the 2 additional " "(optional) shape parameters describe the deviation from the symmetric " "profile. See also options --fep, --sdk or --SDK for more details. " }, { "--fep, --fep-input", "Interpret the shape parameters read from the input list file as " "FWHM, ellipticity and position angle." }, { "--sdk, --sdk-input", "Interpret the shape parameters read from the input list file as " "the sigma, delta and kappa parameters." }, { "--SDK, --SDK-input", "Interpret the shape parameters read from the input list file as " "the Gaussian momenta parameters." }, { "-S, --input-sky, --input-background, --input-image ", "Name of the input file containing the sky level. This file " "should contain at least three columns: the two pixel coordinates " "and the sky vaule. See also --col-pixel and --col-value. " }, { "--col-pixel ,", "Column indices for X and Y (absolute) pixel coordinates. "}, { "--col-value ", "Column index for sky value (intensity)." }, { "--mag-flux ,", "Magnitude - flux conversion level. The specified magnitude will " "be equivalent to the specified flux level." }, { "--integral, --no-monte-carlo", "Draw the stellar profiles to the image using exact integration. " }, { "--monte-carlo, --no-integral", "Draw the stellar profiles to the image using a Monte-Carlo way. " "Note that using this Monte-Carlo method without additional photon " "noise emulation would result assymetric stellar profiles even when " "the profile would be symmetric. Use this option only when " "the --photon-noise option is also used, therefore the profiles " "are strained with photon noise either. " }, { "--noise-suppression ", __extension__ "If the profiles are drawn using exact integration, the profiles would be " "infintely large since an analytical Gaussian profile is positive " "on the whole image domain. In order to limit the integration boundaries, " "this level limits the size of the integration domain, by the following way. " "The expected level of the objects's own photon noise at the edges of the " "integration domain is smaller by this factor at least than the flux " "level. Higher suppression level results larger integration domain. " "In the case of additional photon noise, the default value of 10000.0 " "is satisfactory. For images with no photon noise, this level should " "be increased appropriately. " }, { "--quantize, --no-quantize", "Quantize the output images to integers or not. Note that altering " "this option yields somehow the same as when the bitpix value " "is altered. " }, { "--adus, --no-electrons", "Use the input fluxes as ADUs instead of electrons (default). " }, { "--electrons, --no-adus", "Use the input fluxes as electrons insead of ADUs. " }, { "-g, --gain ", "Electron/ADU ratio (gain)." }, { "Random seeds:", NULL}, { "--seed |auto", "Generic random seed for `firandom`. A literal \"auto\" argument yields " "a random seed derived from random sources available on the " "architecture (/dev/urandom, current time)." }, { "--seed-noise |auto", "Specific random seed for creating background noise." }, { "--seed-spatial |auto", "Specific random seed for creating random spatial coordinates, i.e. " "the random seed for functions in the --list arguments. " }, { "--seed-photon |auto", "Specific random seed for photon noise." }, { "Command line argument combinations:", NULL }, { "--list --output-list ", "This combination creates only a list file based on the --list arguments." }, { "--input-list --output-list ", "This combination just filters and copies the relevant contents " "from the input list to the output list. The shape parameters might " "be converted, for example --SDK-input --fep-output would convert " "Gaussian momenta to FWHM, ellipticity and position angle. " }, { "--list --output [--output-list ]", "This combination creates an artificial list of sources and then creates " "an artificial image with this newly created set of objects. By default, " "the list itself (incl. the centroid coordinates, shape parameters and " "intensities) is not saved unless an output list file is given." }, { "--input-list --list ", "This combination is invalid, the centroid list must either be read " "from a file or created by the program invocation but lists cannot " "be merged this way. In such case, save the object list to a separete " "file and merge the files using standard tools. " }, { NULL, NULL } }; int fprint_firandom_long_help(FILE *fw,int is_wiki) { char *synopsis= "firandom [options] [-o|--output ]"; char *description= "The main purpose of this program is to generate artificial object lists and/or " "artificial (astronomical) images."; fprint_generic_long_help(fw,is_wiki,firandom_long_help,synopsis,description); return(0); } /*****************************************************************************/ int get_seed_arg(char *arg) { int r; if ( strcmp(arg,"auto")==0 ) return(-1); else if ( sscanf(arg,"%d",&r)<1 ) return(0); else if ( r>0 ) return(r); else return(-r); } char *rndfiles[]= { "/dev/urandom", "/dev/random", NULL }; int get_random_seed(void) { FILE *fr; int seed,i; for ( i=0,fr=NULL ; rndfiles[i] != NULL && fr==NULL ; i++ ) { fr=fopen(rndfiles[i],"rb"); if ( fr != NULL ) break; } if ( fr != NULL ) { (void)fread(&seed,1,sizeof(int),fr); fclose(fr); } else { struct timeval tv; gettimeofday(&tv,NULL); seed=tv.tv_usec + (tv.tv_sec<<20); } return(seed); } int set_seed(int *rseed,char *strseed) { if ( strseed==NULL ) { *rseed=0; return(0); } else if ( strcmp(strseed,"auto")==0 ) { *rseed=get_random_seed(); if ( *rseed<0 ) *rseed=-(*rseed); return(0); } else { if ( sscanf(strseed,"%d",rseed)==1 ) return(0); else return(1); } } int main(int argc,char *argv[]) { int i,sx,sy,nseed,pseed,sseed,is_help; double stddev; char *subpixelfile,*psffile,*outfile,*ilist,*olist,*oweight,*ifsky, *stararg,*bgarg,*weightarg,*outmaskname,**maskblocklist; char *saseed,*snseed,*spseed,*ssseed,*fdpstring,*shapepar; int subpixelfile_normalize,is_exact,zoom,wgthsize,wgthzoom; int ilisttype, /* listtype=0: --fep : x,y,flux,FWHM,ELL,PA */ olisttype; /* listtype=1: --sdk : x,y,flux,sigma,delta,kappa */ /* listtype=2: --SDK : x,y,flux,S/D/K momenta */ /* listtype=3: --Smom: x,y,flux,S, M20/M11/M02/...*/ /* listtype=4: --psf : x,y,flux + external PSF! */ /* listtype=5: --psfdst: x,y,flux + PSF + distort */ int is_out_mag; star *stars; int nstar; double ox,oy,scale; fitsdataparam fdp; stargenparam sgp; starlistparam slp; inlistparam ilp; psf tpd; char **mask; int col_pix_x,col_pix_y,col_value; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; is_verbose=is_comment=is_help=0; sx=sy=256; fdp.bitpix=-32; fdp.is_scale=0;fdp.bscale=1.0;fdp.bzero=0.0;fdp.nquantizebit=0; fdpstring=NULL; stddev=0.0;sgp.gain=1.0;sgp.nsuppress=FIRANDOM_DEFAULT_NOISE_SUPPRESSION; sgp.subg=0;sgp.subpixeldata=NULL; sgp.is_photnoise=0; sgp.method=1; sgp.is_intinelect=0; sgp.dontquantize=1; is_exact=0; sgp.tpd=NULL; psffile=NULL;subpixelfile=NULL;subpixelfile_normalize=0; outfile=outmaskname=NULL; ifsky=ilist=olist=oweight=stararg=NULL;weightarg=NULL; ilisttype=olisttype=0; is_out_mag=0; maskblocklist=NULL; slp.mf0.intensity=10000.0, slp.mf0.magnitude= 10.0; sseed=nseed=pseed=0;bgarg=NULL; saseed=ssseed=snseed=spseed=NULL; ilp.listtype=ilisttype, ilp.colx=1,ilp.coly=2, ilp.colflux=3; ilp.colmag=0; col_pix_x=1; col_pix_y=2; col_value=3; shapepar=NULL; zoom=1; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "-h|--help:%f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help, "-o|--output:%s",&outfile, "--output-mask:%s",&outmaskname, "-L|--input-list:%s",&ilist, "-S|--input-sky|--input-background:%s",&ifsky, "-P|--input-psf:%s",&psffile, "-l|--list:%Cr",&stararg, "--output-list:%s",&olist, "--output-weight:%s",&oweight, "-w|--weight:%s",&weightarg, "--fep:" SNf(LISTTYPE_FEP)SNf(LISTTYPE_FEP),&ilisttype,&olisttype, "--fep-input:" SNf(LISTTYPE_FEP),&ilisttype, "--fep-output:" SNf(LISTTYPE_FEP),&olisttype, "--sdk:" SNf(LISTTYPE_SIG)SNf(LISTTYPE_SIG),&ilisttype,&olisttype, "--sdk-input:" SNf(LISTTYPE_SIG),&ilisttype, "--sdk-output:" SNf(LISTTYPE_SIG),&olisttype, "--SDK:" SNf(LISTTYPE_SDK)SNf(LISTTYPE_SDK),&ilisttype,&olisttype, "--SDK-input:" SNf(LISTTYPE_SDK),&ilisttype, "--SDK-output:" SNf(LISTTYPE_SDK),&olisttype, "--Smom:" SNf(LISTTYPE_SMM)SNf(LISTTYPE_SMM),&ilisttype,&olisttype, "--Smom-input:" SNf(LISTTYPE_SMM),&ilisttype, "--Smom-output:" SNf(LISTTYPE_SMM),&olisttype, "--psf:" SNf(LISTTYPE_PSF)SNf(LISTTYPE_PSF),&ilisttype,&olisttype, "--psf-input:" SNf(LISTTYPE_PSF),&ilisttype, "--psf-output:" SNf(LISTTYPE_PSF),&olisttype, "--psfdst:" SNf(LISTTYPE_PDS)SNf(LISTTYPE_PDS),&ilisttype,&olisttype, "--psfdst-input:" SNf(LISTTYPE_PDS),&ilisttype, "--psfdst-output:"SNf(LISTTYPE_PDS),&olisttype, "--col-xy:%Pd,%Pd",&ilp.colx,&ilp.coly, "--col-flux|--col-int:%Pd%SN0f",&ilp.colflux,&ilp.colmag, "--col-mag:%Pd%SN0f",&ilp.colmag,&ilp.colflux, "--col-shape:%s",&shapepar, "--col-pixel:%Pd,%Pd",&col_pix_x,&col_pix_y, "--col-value:%Pd",&col_value, "--write-flux:%SN0f",&is_out_mag, "--write-mag|--write-magnitude:%SN1f",&is_out_mag, "-q|--mask-block:%Dt",&maskblocklist, "-s|--size:%d,%d",&sx,&sy, "-b|--bitpix:%d",&fdp.bitpix, "-D|--data:%s",&fdpstring, "-d|--sky-noise:%g",&stddev, "-m|--sky|--background:%s",&bgarg, "-g|--gain:%g",&sgp.gain, "-z|--zoom:%d",&zoom, "--no-photon-noise:%SN0f",&sgp.is_photnoise, "--photon-noise:%SN1f",&sgp.is_photnoise, "--monte-carlo|--no-integral:%SN0f",&sgp.method, "--integral|--no-monte-carlo:%SN1f",&sgp.method, "--exact:%f",&is_exact, "--noise-suppression:%g",&sgp.nsuppress, "--adus|--no-electrons:%SN0f",&sgp.is_intinelect, "--electrons|--no-adus:%SN1f",&sgp.is_intinelect, "--no-quantize:%SN1f",&sgp.dontquantize, "--quantize:%SN0f",&sgp.dontquantize, "--mag-flux:%g,%g",&slp.mf0.magnitude,&slp.mf0.intensity, "-U|--input-subpixel-structure:%s",&subpixelfile, "--normalize:%f",&subpixelfile_normalize, "--seed:%s",&saseed, "--seed-noise:%s",&snseed, "--seed-spatial:%s",&ssseed, "--seed-photon:%s",&spseed, "--comment:%f",&is_comment,"(C):%f",&is_comment, "--verbose:%i",&is_verbose,"(V):%f",&is_verbose, "*:%e", NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"firandom",FITSH_FIRANDOM_VERSION,is_help); return(0); } else if ( 10 && ilp.colflux>0 ) { fprint_error("invalid combination of command line arguments"); return(1); } else if ( ilp.colflux>0 ) ilp.colflux--,ilp.colmag=-1; else if ( ilp.colmag>0 ) ilp.colmag--,ilp.colflux=-1; else { fprint_error("invalid combination of command line arguments"); return(1); } if ( ilp.colx<0 || ilp.coly<0 ) { fprint_error("invalid column specifications for coordinates"); return(1); } col_pix_x--,col_pix_y--; col_value--; if ( shapepar==NULL ) { ilp.colsh1=3,ilp.colsh2=4,ilp.colsh3=5,ilp.colsh4=6; } else { int j=0; switch ( ilisttype ) { case LISTTYPE_FEP: case LISTTYPE_SIG: case LISTTYPE_SDK: i=sscanf(shapepar,"%d,%d,%d",&ilp.colsh1,&ilp.colsh2,&ilp.colsh3); if ( i<3 ) j=1; else { ilp.colsh1--,ilp.colsh2--,ilp.colsh3--; if ( ilp.colsh1<0 || ilp.colsh2<0 || ilp.colsh3<0 ) { fprint_error("invalid column specifications for shape parameters"); return(1); } } break; case LISTTYPE_SMM: i=sscanf(shapepar,"%d,%d",&ilp.colsh1,&ilp.colsh2); if ( i<2 ) j=1; else { ilp.colsh1--,ilp.colsh2--; if ( ilp.colsh1<0 || ilp.colsh2<0 ) { fprint_error("invalid column specifications for shape parameters"); return(1); } } break; case LISTTYPE_PDS: i=sscanf(shapepar,"%d,%d,%d,%d",&ilp.colsh1,&ilp.colsh2,&ilp.colsh3,&ilp.colsh4); if ( i<4 ) j=1; else { ilp.colsh1--,ilp.colsh2--,ilp.colsh3--,ilp.colsh4--; if ( ilp.colsh1<0 || ilp.colsh2<0 || ilp.colsh3<0 || ilp.colsh4<0 ) { fprint_error("invalid column specifications for shape parameters"); return(1); } } break; } if ( j ) { fprint_error("invalid column specifications for shape parameters in '%s'",shapepar); return(1); } } if ( parse_fits_data_param(fdpstring,&fdp) ) { fprint_error("invalid pixel data format"); return(1); } wgthsize=3,wgthzoom=1; if ( weightarg != NULL ) { i=scanpar(weightarg,SCANPAR_DEFAULT, "hsize:%d",&wgthsize, "zoom:%d",&wgthzoom, NULL); if ( i || wgthsize<0 || wgthzoom<=0 ) { fprint_error("invalid weight specification in '%s",weightarg); return(1); } } if ( psffile != NULL ) { FILE *fr; if ( (fr=fopenread(psffile))==NULL ) { fprint_error("unable to open input PSF file '%s'.",psffile); return(1); } psf_read_fits(fr,&tpd); fclose(fr); sgp.tpd=&tpd; } else sgp.tpd=NULL; if ( is_exact ) { sgp.dontquantize=1; sgp.method=1; sgp.is_photnoise=0; fdp.bitpix=-32; fdp.nquantizebit=0; bgarg=NULL; stddev=0.0; } if ( saseed != NULL ) snseed=spseed=ssseed=saseed; i=0; i |= set_seed(&nseed,snseed); i |= set_seed(&pseed,spseed); i |= set_seed(&sseed,ssseed); if ( i ) { fprint_error("invalid random seed value(s)"); return(1); } ox=0.5*(double)sx, oy=0.5*(double)sy, scale=0.5*(double)sx; if ( subpixelfile != NULL ) { FILE *fr; fr=fopenread(subpixelfile); if ( fr==NULL ) { fprint_error("unable to open subpixel data file"); return(1); } read_subpixel_file(fr,&sgp.subpixeldata,&sgp.subg); fcloseread(fr); if ( subpixelfile_normalize ) normalize_subpixeldata(sgp.subpixeldata,sgp.subg); } if ( ilist != NULL && stararg != NULL ) { fprint_error("ambiguous input source specifications"); return(1); } stars=NULL;nstar=0; if ( ilist != NULL ) { FILE *fr; fr=fopenread(ilist); if ( fr==NULL ) { fprint_error("unable to open input list file"); return(1); } ilp.mf0.magnitude=slp.mf0.magnitude; ilp.mf0.intensity=slp.mf0.intensity; read_input_list(fr,&stars,&nstar,&ilp); fcloseread(fr); } if ( stararg != NULL ) { int r; slp.ox =ox, slp.oy =oy, slp.scale=scale; slp.sx =sx, slp.sy =sy; r=replace_limiters(stararg); if ( r || create_input_list(stararg,&slp,&stars,&nstar,sseed) ) { fprint_error("unable to parse input source argument"); return(1); } } mask=fits_mask_create_empty(sx,sy); for ( i=0 ; maskblocklist != NULL && maskblocklist[i] != NULL ; i++ ) { if ( maskdraw_parse_and_draw(mask,sx,sy,maskblocklist[i])>0 ) { fprint_warning("invalid mask block specification '%s', skipped.\n",maskblocklist[i]); } } if ( outfile != NULL ) { FILE *fw; fits *img; char buff[64]; img=fits_create(); fits_set_standard(img,NULL); fits_alloc_image(img,sx*zoom,sy*zoom); img->i.bit=fdp.bitpix; img->i.curr.bscale=1.0; img->i.curr.bzero=0.0; if ( fdp.is_scale ) img->i.read.bscale=fdp.bscale,img->i.read.bzero=fdp.bzero; else if ( img->i.bit<0 )img->i.read.bscale=1.0,img->i.read.bzero=0.0; else img->i.read.bscale=1.0,img->i.read.bzero=(1<<(img->i.bit-1)); fits_set_image_params(img); sprintf(buff,"Created by firandom, version: %s",FITSH_FIRANDOM_VERSION); fits_set_origin(img,buff,NULL); fits_history_export_command_line(img,"firandom",FITSH_FIRANDOM_VERSION,argc,argv); fits_header_export_command_line(img,"FIRANDOM",NULL,NULL,argc,argv); fits_set_header_double(img,"GAIN",FITS_SH_FIRST,sgp.gain,"photon/ADU value modelled"); random_seed(nseed); if ( create_background(&img->i,bgarg,stddev,ox,oy,scale,zoom) ) { fprint_error("symbolic or syntax error in bacground expression"); return(1); } if ( ifsky != NULL ) { FILE *fr; fr=fopenread(ifsky); if ( fr==NULL ) { fprint_error("unable to open input sky file"); return(1); } while ( ! feof(fr) ) { char *line,**cmd; int n,x,y; double w; if ( (line=freadline(fr))==NULL ) break; remove_newlines_and_comments(line); cmd=tokenize_spaces_dyn(line); for ( n=0 ; cmd != NULL && cmd[n] != NULL ; ) n++; if ( n<=0 ) { if ( cmd != NULL ) free(cmd); free(line); continue; } if ( n<=col_pix_x || n<=col_pix_y || n<=col_value ) { free(cmd); free(line); continue; } if ( sscanf(cmd[col_pix_x],"%d",&x)<1 || sscanf(cmd[col_pix_y],"%d",&y)<1 || sscanf(cmd[col_value],"%lg",&w)<1 ) { free(cmd); free(line); continue; } /* x--,y--; */ /* LR=(0,0)! */ /* see also fiinfo.c */ if ( 0<=x && xi.data[y][x]=w; /* fprintf(stderr,"n=%d x=%d y=%d w=%g sx=%d sy=%d\n",n,x,y,w,sx,sy); */ } free(cmd); free(line); } fcloseread(fr); } if ( sgp.is_intinelect ) divide_image(&img->i,sgp.gain); if ( stars != NULL && nstar>0 ) { random_seed(pseed); draw_starlist(&img->i,&sgp,stars,nstar,zoom); } if ( ! sgp.dontquantize ) quantize_image(&img->i); else if ( fdp.nquantizebit>0 ) fits_image_quantize(&img->i,fdp.nquantizebit); fits_backscale(img,img->i.read.bscale,img->i.read.bzero); mark_integerlimited_pixels(&img->i,mask,img->i.bit,1,MASK_OVERSATURATED,MASK_OVERSATURATED); if ( mask != NULL && (!fits_mask_is_clean(mask,sx,sy)) ) fits_mask_export_as_header(&img->header,1,mask,sx,sy,NULL); fw=fopenwrite(outfile); if ( fw==NULL ) { fprint_error("unable to create output file '%s'",outfile); return(1); } fits_write(fw,img); fclosewrite(fw); fits_free(img); } if ( outmaskname != NULL ) { FILE *fw; fits *img; char buff[64]; img=fits_create(); fits_set_standard(img,NULL); img->i.bit=fdp.bitpix; img->i.curr.bscale=1.0; img->i.curr.bzero=0.0; if ( fdp.is_scale ) img->i.read.bscale=fdp.bscale,img->i.read.bzero=fdp.bzero; else if ( img->i.bit<0 )img->i.read.bscale=1.0,img->i.read.bzero=0.0; else img->i.read.bscale=1.0,img->i.read.bzero=(1<<(img->i.bit-1)); fits_set_image_params(img); sprintf(buff,"Created by firandom, version: %s",FITSH_FIRANDOM_VERSION); fits_set_origin(img,buff,NULL); fits_history_export_command_line(img,"firandom",FITSH_FIRANDOM_VERSION,argc,argv); fits_header_export_command_line(img,"FIRANDOM",NULL,NULL,argc,argv); fits_set_header_double(img,"GAIN",FITS_SH_FIRST,sgp.gain,"photon/ADU value modelled"); if ( mask != NULL ) fits_mask_export_as_header(&img->header,1,mask,sx,sy,NULL); fw=fopenwrite(outmaskname); if ( fw==NULL ) { fprint_error("unable to create output mask file"); return(1); } fits_write(fw,img); fclosewrite(fw); fits_free(img); } if ( mask != NULL ) fits_mask_free(mask); if ( oweight != NULL ) { FILE *fw; fits *img; char buff[64]; weightlist wl; weight_draw(&wl,stars,nstar,wgthsize,wgthzoom,sgp.tpd); img=weight_fits_create(&wl); sprintf(buff,"Created by firandom, version: %s",FITSH_FIRANDOM_VERSION); fits_set_origin(img,buff,NULL); fits_header_export_command_line(img,"FIRANDOM",NULL,NULL,argc,argv); fw=fopenwrite(oweight); if ( fw==NULL ) { fprint_error("unable to create output weight file '%s'",oweight); return(1); } fits_write(fw,img); fclosewrite(fw); fits_free(img); } if ( olist != NULL ) { FILE *fw; fw=fopenwrite(olist); if ( fw==NULL ) { fprint_error("unable to create output list file '%s'",olist); return(1); } if ( is_out_mag ) write_output_list(fw,stars,nstar,olisttype,&slp.mf0); else write_output_list(fw,stars,nstar,olisttype,NULL); fclosewrite(fw); } return(0); } fitsh-0.9.2/src/stars.h0000644000175000017500000002555211236250013013351 0ustar apalapal/*****************************************************************************/ /* stars.h */ /*****************************************************************************/ #ifndef __STARS_H_INCLUDED #define __STARS_H_INCLUDED 1 #include #include "background.h" typedef struct { int xmin,xmax; int ymin,ymax; } range; #ifndef __IPOINT_STRUCT_DEFINED #define __IPOINT_STRUCT_DEFINED typedef struct { int x,y; } ipoint; #endif typedef struct { ipoint *ipoints; int nipoint; } ipointlist; typedef struct { ipoint *ipoints; double *yvals; int nipoint; } mpointlist; typedef struct { int ix,iy; /* Integer coordinates of a star can-*/ /* didate, the image has a local max-*/ /* imum in the point (ix,iy), or */ /* something like that... */ double cx,cy; /* A better approximation for the */ /* center of a star candidate, deri- */ /* ved by a second-order polynomial */ /* fit (or something else, see also */ /* refine_candidate_params()... */ double peak,amp,bg; double sxx,syy,sxy; /* Other parameters derived from this*/ /* second-order polynomial fit. */ /* All of these parameters are set */ /* by search_star_candidates() and */ /* some of them are used by */ /* markout_stars() and */ /* fit_gaussians(). */ ipoint *ipoints; /* ipoints[] contains nipoint */ int nipoint; /* elements, (x,y) pairs, which */ /* possible belong to the star. */ /* Determined by markout_*() and */ /* used by fit_gaussians(). */ double area, /* area (it is always an integer) */ noise, /* bg noise */ flux; /* flux */ int flags,marked; } candidate; #include "psf.h" #define SHAPE_GAUSS 1 #define SHAPE_ELLIPTIC 2 #define SHAPE_DEVIATED 3 #define SHAPE_PSF 4 #define MAX_DEVIATION_ORDER 4 #define MAX_DEVIATION_COEFF 15 /* (MDO+1)*(MDO+2)/2 */ /* #define STAR_MULTIMODEL 1 */ /* obsoleted */ typedef struct { double gamp,gbg; double gcx,gcy; } starlocation; typedef struct { int model,order; /* `model` can be: SHAPE_GAUSS, ELLIPTIC, */ /* DEVIATED. `order` is only defined */ /* for SHAPE_DEVIATED (act. between 2 and 4) */ /* PSF fit results are stored in another */ /* form (see (starlocation)star->psf). */ double gs,gd,gk,gl; /* coeff's for SHAPE_ELLIPTIC (gs, gd, gk), */ /* DEVIATED (gs) and PSF (gs, gd, gk and gl).*/ double mom[MAX_DEVIATION_COEFF]; /* coeff's for SHAPE_DEVIATED*/ double factor; /* factor of multi-model fitting (should not */ /* really expand out from the interval [0,1])*/ } starshape; typedef struct { starlocation location; /* An approximation for the center, */ /* background and amplitude of the */ /* star (`gamp` is model-dependent). */ starshape shape; /* Shape parameters of the star. */ starlocation psf; /* PSF fitting yields only info's */ /* like this: centroid coordinates, */ /* background and amplitude (later is*/ /* equivalent to the total flux...). */ double gsig,gdel,gkap; /* Derived parameters from the Gau- */ double gfwhm, /* sian fit (FWHM, ellpticity and */ gellip, /* position angle), also set by */ gpa; /* fit_gaussians(). */ double flux; /* The total flux of the star. */ /* Set by fit functions, and used */ /* by firandom also. */ int marked; /* A flag for cleanup_starlist(). */ candidate *cand; /* candidate pointer (if available). */ } star; /* temporary removed from typedef struct { ... } star; */ #ifdef STAR_MULTIMODEL starshape *mshapes; /* Shape parameters of the star if */ int nmshape; /* multi-model fitting was used. */ #endif typedef struct { int ix,iy; double value; } imgpoint; typedef struct { int model; /* can be SHAPE_{GAUSS,ELLIPTIC,DEVIATED} */ int order; /* up to MAX_DEVIATION_ORDER, only for SHAPE_DEVIATED*/ /* double igs;*/ /* initial value of the 'gs' starshape parameter */ } starmodelfit; /* star-base.c */ /***********************************************************/ /* fit_small_parabola_{point,block,block_param}(): Some common parabola fitting routines used during candidate searching (see the appropriate star-cand-*.c modules). */ int fit_small_parabola_point(fitsimage *img,int x,int y,double *fit); int fit_small_parabola_block(fitsimage *img,int x,int y,double *fit); int fit_small_parabola_block_param(fitsimage *img,int j,int i,double *rcx,double *rcy,double *raxx,double *raxy,double *rayy,double *rpeak); /* order_candidates_by_peak(): Orders star candidate array cands[] (with 'ncand' elements) by peak. */ int order_candidates_by_peak(candidate *cands,int ncand); /* refine_candidate_params(): Refines the candidate parameters - the centroid coordinates and the shape parameters - of the candidates in the array cands[]. This refine method is based on the calculation of the central momenta (up to order of 2) of the points belonging to the given star candidate. */ int refine_candidate_params(fitsimage *img,candidate *cands,int ncand); int star_set_common_shape_params(double gs,double gd,double gk,star *ws); double star_get_unity_flux(starshape *sw); /* convert_candidates(): Convert candidate information into star information. The stars are modelled by an elliptical Gaussian function (so, star->model is SHAPE_ELLIPTIC), the parameters (gs, gd, gk, amplitude, ...) are calculated from the approximations sxx, sxy, syy (see the definition of the 'star' and 'candidate' structures). */ int convert_candidates(candidate *cands,int ncand,star **rstars,int *rnstar); /* cleanup_candlist(), cleanup_starlist(): Remove marked candidates/stars from the arraies pointed by rcands and rstars respectively. */ int cleanup_candlist(candidate **rcands,int *rncand); int cleanup_starlist(star **rstars,int *rnstar); /* free_stars(), free_candidates(): Releases fully the array 'stars' and 'cands' (thus all internal dynamical allocations are also freed). */ int free_stars(star *stars,int nstar); int free_candidates(candidate *cands,int ncand); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ typedef struct { void (*funct)(void *,double *,double *,double *,void *); int nshape; void *param; } modelparam; /* model_merge(), model_combine(): Combination of star-models (including PSF). The parameter 'p' has a type of 'modelparam[]', an array of a set of models described by 'funct' and 'nshape' number of shape parameters. */ void model_merge(void *xpnt,double *a,double *yy,double *dyda,void *p); void model_combine(void *xpnt,double *a,double *yy,double *dyda,void *p); /* star-model.c */ /**********************************************************/ void gauss_1d_prof(void *xpnt,double *a,double *yy,double *dyda); void gauss_2d_nmom(void *xpnt,double *a,double *yy,double *dyda); void gauss_2d_wmom(void *xpnt,double *a,double *yy,double *dyda); void gauss_2d_nmom_subps(void *xpnt,double *a,double *yy,double *dyda); void gauss_2d_wmom_subps(void *xpnt,double *a,double *yy,double *dyda); #define FIT_AB 0x01 #define FIT_XY 0x02 #define FIT_WIDTH 0x04 #define FIT_DEVIATION 0x08 typedef struct { int fit_flags; int iter_symmetric; int iter_general; } starfit; int fit_star_single_model(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,starfit *fgp,int model,int modelorder); #ifdef STAR_MULTIMODEL int fit_star_multi_models(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,starfit *fgp,starmodelfit *smfs,int nsmf); int fit_star_model(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,starfit *fgp,int model,int modelorder); #endif int collective_fit_star_single_model(fitsimage *img,char **mask, star *stars,int nstar,ipointlist *ipl, starfit *sfp,int is_putback,int level); int collective_fit_star_single_model_iterative(fitsimage *img,char **mask, star *stars,int nstar,ipointlist *ipl, starfit *sfp,int level,int niter); int collective_fit_star_single_model_blocked(fitsimage *img,char **mask, star *stars,int nstar,ipointlist *ipl,double bhsize); /* star-psf.c */ /************************************************************/ typedef struct { int iterations; } psffit; int fit_star_psf_native(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,psffit *pfp,psf *tpd); int fit_star_psf(fitsimage *img,char **mask,candidate *cands,int ncand, star **rstars,int *rnstar,psffit *pfp,psf *tpd); /* star-cand-pp.c */ /********************************************************/ int search_star_candidates(fitsimage *img,char **mask, candidate **rcands,int *rncand,range *srcrange, double threshold,spatial *bg,double skysigma); int markout_candidates(fitsimage *img,char **mask,candidate *cands,int ncand); /* star-cand-biq.c */ /*******************************************************/ int search_star_candidates_biquad(fitsimage *img,char **mask, candidate **rcands,int *rncand,range *srcrange); /* star-cand-trb.c */ /*******************************************************/ int search_star_candidates_trb(fitsimage *img,char **mask, candidate **rcands,int *rncand,range *srcrange, double treshold); /* star-cand-lnk.c */ /*******************************************************/ int search_star_candidates_link(fitsimage *img,char **mask, candidate **rcands,int *rncand,range *srcrange, double threshold,double fluxthreshold,double critical_prominence); /* star-draw.c */ /***********************************************************/ /* star_draw_gauss(), star_draw_deviated(), star_draw_psf(): Draws analytic stars with the profile models Gaussian, deviated or PSF-based. The star will be written to the array 'iarr' with the size of 'sx' time 'sy'. The center of the star profile is (x0,y0). The additional parameters are model-dependent (is, id, ik: covariance parameters for Gaussian profile; gs, order, mom: central coefficient, order and moments for deviated profiles and the PSF 'p' itself with extra parameters /px, py, is, id, ik and il/). */ int star_draw_gauss (double **iarr,int sx,int sy, double x0,double y0,double is,double id,double ik); int star_draw_deviated (double **iarr,int sx,int sy, double x0,double y0,double gs,int order,double *mom); int star_draw_psf (double **iarr,int sx,int sy, double x0,double y0,psf *p,double px,double py, double is,double id,double ik,double il); /*****************************************************************************/ int drawback_model(ipoint *ipoints,int nipoint,double *yvals, starlocation *loc,starshape *shp,double mul); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/str.c0000644000175000017500000000355411021230432013011 0ustar apalapal/*****************************************************************************/ /* str.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Some functions related to (dynamic) string handling. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2006; Pal, A. (apal@szofi.elte.hu) */ /*****************************************************************************/ #include #include #include #include #include "str.h" /*****************************************************************************/ char * strkcpy(char *out,char *in,int size) { strncpy(out,in,size); out[size-1]=0; return(out); } /*****************************************************************************/ int strappend(char **str,char *cat) { int l1,l2; if ( str==NULL ) return(-1); else if ( *str==NULL ) { *str=strdup(cat); return(0); } else { l1=strlen(*str); l2=strlen(cat); *str=realloc(*str,l1+l2+1); strcpy((*str)+l1,cat); return(0); } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int vstrappendf(char **str,char *fmt,va_list ap) { int n,l,size; if ( str==NULL ) return(0); if ( *str==NULL ) l=0; else l=strlen(*str); size=128; *str=realloc(*str,l+size); if ( *str==NULL ) return(-1); while ( 1 ) { n=vsnprintf((*str)+l,size,fmt,ap); if ( n>-1 && n-1 ) size=n+1; else size=size*2; if ( (*str=realloc(*str,l+size))==NULL ) return(-1); }; return(0); } int strappendf(char **str,char *fmt,...) { int ret; va_list ap; va_start(ap,fmt); ret=vstrappendf(str,fmt,ap); va_end(ap); return(ret); } /*****************************************************************************/ fitsh-0.9.2/src/combine.h0000644000175000017500000000522211467567636013655 0ustar apalapal/*****************************************************************************/ /* combine.h */ /*****************************************************************************/ #ifndef __COMBINE_H_INCLUDED #define __COMBINE_H_INCLUDED 1 /*****************************************************************************/ #include #include "fitsmask.h" /*****************************************************************************/ /* classic averaging modes (REJ_AVG and REJ_MED uses `niter` and `[lh]sigma`)*/ #define COM_MODE_AVG 0 /* average, simple mean */ #define COM_MODE_MED 1 /* median */ #define COM_MODE_REJ_AVG 2 /* sigma rejection mean */ #define COM_MODE_REJ_MED 3 /* sigma rejection median */ /* some other combinations for other purposes: */ #define COM_MODE_SUM 4 /* sum of the images/pixels */ #define COM_MODE_SQSUM 5 /* squared sum */ #define COM_MODE_SCT 6 /* standard deviation */ #define COM_MODE_MIN 8 /* minimum */ #define COM_MODE_MAX 9 /* maximum */ #define COM_MODE_REJ_DEPRECATED 255 /* old stuff */ /* ignore modes: */ #define COM_IGNORE_NEGATIVE 0x01 #define COM_IGNORE_ZERO 0x02 #define COM_IGNORE_POSITIVE 0x04 typedef struct { fitsimage *img; double scale; int x0,y0; } presubdata; typedef struct { int mode; /* see COM_MODE_* definition */ int niter; /* used by COM_MODE_REJ_* */ double lower,upper; /* used by COM_MODE_REJ_* */ int ignore_flag; /* see COM_IGNORE_* */ int logicalmethod; /* (0): or (!0): and */ } compar; typedef struct { fits *img; FILE *fr; } comimg; /*****************************************************************************/ /* Combination of images: user interface specific stuff (gonna be removed?!) */ int combine_parse_mode(char *modstr,compar *cp); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Combination of images: lower and higher level combination specific stuff */ double combine_points(double *points,int n,compar *cp); int combine_lines(double **lines,int n,int sx,double *out, compar *cp,char **wmask,char *outmask); int combine_images_from_files(comimg *inputs,int n,fits *outimg, compar *cp,char **inmask,char **outmask, presubdata *pss,int nps,size_t maxmem); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int combine_cleanup(comimg *inputs,int ninput); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/src/apphot.c0000644000175000017500000004771112771247752013531 0ustar apalapal/*****************************************************************************/ /* apphot.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Low-level aperture-photometry routines. */ /*****************************************************************************/ #include #include #include #include #include #include "fitsh.h" #include "math/spline/spline.h" #include "math/spline/biquad.h" #include "math/spline/biquad-isc.h" #include "math/intersec/intersec.h" #include "math/intersec/intersec-cri.h" #include "math/polygon.h" #include "statistics.h" #include "tensor.h" #include "apphot.h" /*****************************************************************************/ static int fracpixel_compare(const void *p1,const void *p2) { if ( ((fracpixel *)p1)->flux < ((fracpixel *)p2)->flux ) return(-1); else return(1); } int fracpixel_order(fracpixel *fp,int n) { qsort((void *)fp,n,sizeof(fracpixel),fracpixel_compare); return(0); } #define FRACPIXEL_MEDIAN_SPLINE double fracpixel_median(fracpixel *fp,int n) { int i; double a,area,median; double *x,*y,*y2; #ifndef FRACPIXEL_MEDIAN_SPLINE double halfval; int j; #endif x=y=y2=NULL; fracpixel_order(fp,n); for ( i=0,area=0.0 ; ira, da =par->da; hsan=(int)(ra+da+3.0); ix=(int)floor(cx); iy=(int)floor(cy); annin.x=annout.x=cx, annin.y=annout.y=cy; annin.radius=ra; annout.radius=ra+da; n=(2*hsan+1)*(2*hsan+1); bgxs=(fracpixel *)malloc(sizeof(fracpixel)*n); nbgx=0; wr=sqrt(0.5); ril2=(ra-wr)*(ra-wr), rol2=(ra+da+wr)*(ra+da+wr); flann=arann=0.0; for ( i=iy-hsan ; i<=iy+hsan ; i++ ) { if ( i<0 || i>=sy ) continue; for ( j=ix-hsan ; j<=ix+hsan ; j++ ) { drectangle pixel; double a,dx,dy,d2,p; if ( j<0 || j>=sx ) continue; if ( mask != NULL && mask[i][j] ) continue; pixel.x=(double)j, pixel.y=(double)i; p=data[i][j]; dx=(double)j-cx, dy=(double)i-cy; d2=dx*dx+dy*dy; if ( d2 <= ril2 || rol2 <= d2 ) continue; pixel.sx=pixel.sy=1.0; a=area_intersec_of_rect_circ(&pixel,&annout)- area_intersec_of_rect_circ(&pixel,&annin ); if ( a<=0.0 ) continue; bgxs[nbgx].area=a, bgxs[nbgx].flux=p; flann += a * p, arann += a; nbgx++; } } if ( nbgx==0 ) { free(bgxs);return(1); } /* Read iterative sigma rejection parameters from (apphotpar *)par: */ n_iterations=par->bgm.rejniter; reject_lower=par->bgm.rejlower; reject_upper=par->bgm.rejupper; /* Discard and reset illegal values of the sigma rejection parameters: */ if ( n_iterations<1 ) n_iterations=1; if ( reject_lower<=0.0 ) n_iterations=1; if ( reject_upper<=0.0 ) n_iterations=1; prevarann=bgavg=0.0; #ifdef DEBUG_APPHOT_BACK fprintf(stderr,"[%g",arann); #endif bgsigma=0.0; for ( i=0 ; i0 && prevarann==arann ) break; prevarann=arann; bgavg=fracpixel_median(bgxs,nbgx); #ifdef DEBUG_APPHOT_BACK fprintf(stderr,"(%g,%g,%g)",arann,bgavg,bgsigma); #endif if ( i=cv+width ) { if ( i-lmin > kmax-kmin ) { kmin=lmin; kmax=i; } lmin=i; cv+=width; } } if ( n-lmin > kmax-kmin ) { kmin=lmin; kmax=n; } sum=0.0; for ( i=kmin ; ira, da =par->da; hsize=(int)(ra+da+2.0); fsize=2*hsize+1; ix=(int)floor(cx); iy=(int)floor(cy); bgs=(double *)malloc(sizeof(double)*fsize*fsize); nbg=0; ril2=ra*ra, rol2=(ra+da)*(ra+da); atot=abad=0; for ( i=iy-hsize ; i<=iy+hsize ; i++ ) { for ( j=ix-hsize ; j<=ix+hsize ; j++ ) { dx=(double)j+0.5-cx, dy=(double)i+0.5-cy; dd=dx*dx+dy*dy; if ( dd < ril2 || rol2 < dd ) continue; atot++; if ( i<0 || i>=sy || j<0 || j>=sx ) { abad++;continue; } if ( mask != NULL && mask[i][j] ) { abad++;continue; } if ( ringmask!= NULL && ringmask[i][j] ){ abad++;continue; } p=data[i][j]; bgs[nbg]=p; nbg++; } } if ( ratot != NULL ) *ratot=atot; if ( rabad != NULL ) *rabad=abad; if ( nbg<=2 ) { free(bgs);return(1); } /* Read iterative sigma rejection parameters from (apphotpar *)par: */ type=par->bgm.type; n_iterations=par->bgm.rejniter; reject_lower=par->bgm.rejlower; reject_upper=par->bgm.rejupper; /* Discard and reset illegal values of the sigma rejection parameters: */ if ( n_iterations<1 ) n_iterations=1; if ( reject_lower<=0.0 ) n_iterations=1; if ( reject_upper<=0.0 ) n_iterations=1; bds=(double *)malloc(sizeof(double)*fsize*fsize); fbg=0;lbg=nbg-1; median(bgs,nbg); /* avg=0.0; get_histogram_peak(bgs,nbg,10.0,&avg); flx=0.0; for ( i=0 ; i0 ) { n=lbg-fbg+1; for ( i=fbg,sum=0.0 ; i<=lbg ; i++ ) { sum+=bgs[i]; } min=bgs[fbg]; max=bgs[lbg]; mean=sum/(double)n; med=0.5*(bgs[fbg+n/2]+bgs[fbg+(n-1)/2]); flx=sum; switch ( type ) { case BGTYPE_MEAN: avg=mean; break; case BGTYPE_MEDIAN: avg=med; break; case BGTYPE_MODE: mode=3.0*med-2.0*mean; if ( modemax ) mode=max; avg=mode; break; default: avg=mean; break; } std=0.0; for ( i=0 ; i0 ) std/=(double)n; else std=0.0; sig=median(bds,n); n_iterations--; if ( n_iterations>0 && n>2 ) { i=0; while ( fbgavg+reject_upper*sig ) lbg--,i++; if ( i==0 ) n_iterations=0; } } *rbgarea=(double)nbg; *rbgflux=flx; *rbgavg=avg; *rbgsigma=sqrt(std); free(bds); free(bgs); return(0); } int aperture_photometry_back_polygons(double **data,char **mask,int sx,int sy, double cx,double cy,apphotpar *par, double *rbgarea,double *rbgflux,double *rbgavg,double *rbgsigma, int *ratot,int *rabad,char **ringmask) { int i,j,ix,iy,hsize,fsize,nbg,atot,abad; double *bgs,*bds; double med,sig,std,sum,mean,mode,min,max,avg,flx,p,w; int n_iterations,type,fbg,lbg,n; double reject_lower,reject_upper; double *xpolypoints; int nxpolypoint; if ( data==NULL ) return(1); hsize=0; for ( i=0 ; inda ; i++ ) { int ax,ay; double x,y; x=par->da_poly[2*i+0]; y=par->da_poly[2*i+1]; if ( x<0 ) x=-x; if ( y<0 ) y=-y; ax=(int)x+1; ay=(int)y+1; if ( hsizendanra?par->nra:par->nda); fsize=2*hsize+1; ix=(int)floor(cx); iy=(int)floor(cy); bgs=(double *)malloc(sizeof(double)*fsize*fsize); nbg=0; atot=abad=0; xpolypoints=(double *)malloc(sizeof(double)*2*(nxpolypoint+16)); for ( i=iy-hsize ; i<=iy+hsize ; i++ ) { for ( j=ix-hsize ; j<=ix+hsize ; j++ ) { double a1,a0; int k; for ( k=0 ; knda ; k++ ) { xpolypoints[2*k+0]=par->da_poly[2*k+0]+cx; xpolypoints[2*k+1]=par->da_poly[2*k+1]+cy; } nxpolypoint=polygon_intersection_square(xpolypoints,par->nda,(double)j,(double)i,1.0,1.0); a1=polygon_area(xpolypoints,nxpolypoint); for ( k=0 ; knra ; k++ ) { xpolypoints[2*k+0]=par->ra_poly[2*k+0]+cx; xpolypoints[2*k+1]=par->ra_poly[2*k+1]+cy; } nxpolypoint=polygon_intersection_square(xpolypoints,par->nra,(double)j,(double)i,1.0,1.0); a0=polygon_area(xpolypoints,nxpolypoint); /* continue if pixel (j,i) is not in the aperture: */ if ( ! ( 0.0 < a1 && a0 <= 0.0 ) ) continue; atot++; if ( i<0 || i>=sy || j<0 || j>=sx ) { abad++;continue; } if ( mask != NULL && mask[i][j] ) { abad++;continue; } if ( ringmask!= NULL && ringmask[i][j] ){ abad++;continue; } p=data[i][j]; bgs[nbg]=p; nbg++; } } if ( ratot != NULL ) *ratot=atot; if ( rabad != NULL ) *rabad=abad; if ( nbg<=2 ) { free(bgs);return(1); } /* Read iterative sigma rejection parameters from (apphotpar *)par: */ type=par->bgm.type; n_iterations=par->bgm.rejniter; reject_lower=par->bgm.rejlower; reject_upper=par->bgm.rejupper; /* Discard and reset illegal values of the sigma rejection parameters: */ if ( n_iterations<1 ) n_iterations=1; if ( reject_lower<=0.0 ) n_iterations=1; if ( reject_upper<=0.0 ) n_iterations=1; bds=(double *)malloc(sizeof(double)*fsize*fsize); fbg=0;lbg=nbg-1; median(bgs,nbg); /* avg=0.0; get_histogram_peak(bgs,nbg,10.0,&avg); flx=0.0; for ( i=0 ; i0 ) { n=lbg-fbg+1; for ( i=fbg,sum=0.0 ; i<=lbg ; i++ ) { sum+=bgs[i]; } min=bgs[fbg]; max=bgs[lbg]; mean=sum/(double)n; med=0.5*(bgs[fbg+n/2]+bgs[fbg+(n-1)/2]); flx=sum; switch ( type ) { case BGTYPE_MEAN: avg=mean; break; case BGTYPE_MEDIAN: avg=med; break; case BGTYPE_MODE: mode=3.0*med-2.0*mean; if ( modemax ) mode=max; avg=mode; break; default: avg=mean; break; } std=0.0; for ( i=0 ; i0 ) std/=(double)n; else std=0.0; sig=median(bds,n); n_iterations--; if ( n_iterations>0 && n>2 ) { i=0; while ( fbgavg+reject_upper*sig ) lbg--,i++; if ( i==0 ) n_iterations=0; } } *rbgarea=(double)nbg; *rbgflux=flx; *rbgavg=avg; *rbgsigma=sqrt(std); free(bds); free(bgs); return(0); } double weighted_intersection(drectangle *pixel,dcircle *aperture, double **subpixeldata,int gx,int gy) { int i,j; double a; drectangle p; a=0.0; p.sx=pixel->sx/(double)gx; p.sy=pixel->sy/(double)gy; for ( i=0 ; iy+(double)i*pixel->sy/(double)gy; for ( j=0 ; jx+(double)j*pixel->sx/(double)gx; a+=area_intersec_of_rect_circ(&p,aperture)*subpixeldata[i][j]; } } return(a); } typedef struct { int hsap; double dx,dy,r0; double **arr; } apphotcache; #define AC_TOLERANCE (1e-7) int aperture_photometry_flux_circle(double **data,char **mask,int sx,int sy, double cx,double cy,double r0,double *rarea,double *rflux, apphot_out *out,double background, int *rrtot,int *rrbad,int *rrign, int maskignore,double **subpixeldata,int subg,char **xmask) { int i,j,ix,iy; int hsap; int cflag,flag,rtot,rbad,rign; double flux,area,fcoeff[6]; dcircle aperture; static apphotcache ac = { 0, 0.0, 0.0, 0.0, NULL }; if ( data==NULL ) return(1); if ( rflux==NULL ) return(0); hsap=(int)(r0+2.0); ix=(int)floor(cx); iy=(int)floor(cy); aperture.x=cx, aperture.y=cy; aperture.radius=r0; area=flux=0.0; flag=0,rtot=rbad=rign=0; if ( subg<=0 ) subpixeldata=NULL; else if ( subpixeldata==NULL ) subg=0; if ( out != NULL ) { out->fw=0.0; out->fwx=out->fwy=0.0; out->fwxx=out->fwxy=out->fwyy=0.0; } if ( subpixeldata==NULL ) { dcircle dc; drectangle dr; double dx,dy; dx=cx-(double)ix; dy=cy-(double)iy; if ( ! ( ac.r0==r0 && ac.hsap==hsap && fabs(dx-ac.dx)0.0 ) { if ( i<0 || i>=sy || j<0 || j>=sx ) cflag |= MASK_OUTER,a=0.0; else { if ( mask != NULL && mask[i][j] ) cflag |= mask[i][j]; if ( xmask != NULL && xmask[i][j] ) cflag |= xmask[i][j]; } } else continue; if ( (! (cflag & MASK_OUTER)) && (cflag&(~maskignore))==0 ) { flux += a * data[i][j]; area += a; if ( out != NULL ) { double d; d=data[i][j]-background; out->fw += fcoeff[0]*d; out->fwx += fcoeff[1]*d; out->fwy += fcoeff[2]*d; out->fwxx += fcoeff[3]*d; out->fwxy += fcoeff[4]*d; out->fwyy += fcoeff[5]*d; } } rtot++; if ( cflag ) { rbad++; if ( (cflag&(~maskignore))==0 ) rign++; } flag |= cflag; } } if ( rrtot != NULL ) *rrtot=rtot; if ( rrbad != NULL ) *rrbad=rbad; if ( rrign != NULL ) *rrign=rign; *rarea=area; *rflux=flux; return(flag); } int aperture_photometry_flux_polygon(double **data,char **mask,int sx,int sy, double cx,double cy,double *poly,int nppoly,double *rarea,double *rflux, apphot_out *out,double background, int *rrtot,int *rrbad,int *rrign, int maskignore,char **xmask) { int i,j,ix,iy; int hsapx,hsapy; int cflag,flag,rtot,rbad,rign; double flux,area,fcoeff[6]; double *xpolypoints; int nxpolypoint; for ( i=0 ; i<6 ; i++ ) { fcoeff[i]=0.0; } if ( data==NULL ) return(1); if ( rflux==NULL ) return(0); hsapx=hsapy=2; for ( i=0 ; ifw=0.0; out->fwx=out->fwy=0.0; out->fwxx=out->fwxy=out->fwyy=0.0; } xpolypoints=(double *)malloc(sizeof(double)*2*(nppoly+16)); for ( i=iy-hsapy ; i<=iy+hsapy ; i++ ) { for ( j=ix-hsapx ; j<=ix+hsapx ; j++ ) { int k; double a; for ( k=0 ; k0.0 ) { if ( i<0 || i>=sy || j<0 || j>=sx ) cflag |= MASK_OUTER,a=0.0; else { if ( mask != NULL && mask[i][j] ) cflag |= mask[i][j]; if ( xmask != NULL && xmask[i][j] ) cflag |= xmask[i][j]; } } else continue; if ( (! (cflag & MASK_OUTER)) && (cflag&(~maskignore))==0 ) { flux += a * data[i][j]; area += a; if ( out != NULL ) { double d; d=data[i][j]-background; out->fw += fcoeff[0]*d; out->fwx += fcoeff[1]*d; out->fwy += fcoeff[2]*d; out->fwxx += fcoeff[3]*d; out->fwxy += fcoeff[4]*d; out->fwyy += fcoeff[5]*d; } } rtot++; if ( cflag ) { rbad++; if ( (cflag&(~maskignore))==0 ) rign++; } flag |= cflag; } } free(xpolypoints); if ( rrtot != NULL ) *rrtot=rtot; if ( rrbad != NULL ) *rrbad=rbad; if ( rrign != NULL ) *rrign=rign; *rarea=area; *rflux=flux; return(flag); } int aperture_photometry(fitsimage *img,char **mask, double cx,double cy,apphotpar *par,double *rflux,double *rfluxerr) { double bgarea,bgflux,bgavg,bgsigma; double area,flux,fluxerr; int r; if ( img==NULL || img->data==NULL ) return(1); if ( img->sx<=0 || img->sy<=0 ) return(1); r=aperture_photometry_back_ring(img->data,mask,img->sx,img->sy,cx,cy,par,&bgarea,&bgflux,&bgavg,&bgsigma,NULL,NULL,NULL); if ( r ) return(1); r=aperture_photometry_flux_circle(img->data,mask,img->sx,img->sy,cx,cy,par->r0,&area,&flux,NULL,0.0,NULL,NULL,NULL,0,NULL,0,NULL); if ( r ) return(1); flux -= bgavg * area; *rflux =flux; if ( rfluxerr != NULL ) { fluxerr = sqrt ( flux + area * (bgsigma*bgsigma)*(1.0+1.0/bgarea) ); *rfluxerr=fluxerr/sqrt(par->gain); } return(0); } /*****************************************************************************/ int aperture_photometry_flux_biquad(double **c,char **mask,int sx,int sy, double cx,double cy,double r0,double *rarea,double *rflux, int *rrtot,int *rrbad,int *rrign,int maskignore,char **xmask) { int i,j,ix,iy,rtot,rbad,flag,rign,cflag; int hsap; double flux,area; dcircle aperture; if ( c==NULL ) return(1); if ( rflux==NULL ) return(0); hsap=(int)(r0+2.0); ix=(int)floor(cx); iy=(int)floor(cy); aperture.x=cx, aperture.y=cy; aperture.radius=r0; area=flux=0.0; rtot=rbad=rign=0;flag=0; for ( i=iy-hsap ; i<=iy+hsap ; i++ ) { for ( j=ix-hsap ; j<=ix+hsap ; j++ ) { drectangle pixel; double a,f; pixel.x=(double)j, pixel.y=(double)i; pixel.sx=pixel.sy=1.0; a=area_intersec_of_rect_circ(&pixel,&aperture); cflag=0; if ( a>0.0 ) { if ( i<0 || i>=sy || j<0 || j>=sx ) cflag |= MASK_OUTER,a=0.0; if ( mask != NULL && ! (cflag&MASK_OUTER) && mask[i][j] ) cflag |= mask[i][j]; if ( xmask != NULL && ! (cflag&MASK_OUTER) && xmask[i][j] ) cflag |= xmask[i][j]; } else continue; if ( ! (cflag & MASK_OUTER) && (cflag&(~maskignore))==0 ) { area += a; f=biquad_isc_int_pixel_circle(c,j,i,cx,cy,r0); flux += f; } rtot++; if ( cflag ) { rbad++; if ( (cflag&(~maskignore))==0 ) rign++; } flag |= cflag; } } if ( rrtot != NULL ) *rrtot=rtot; if ( rrbad != NULL ) *rrbad=rbad; if ( rrign != NULL ) *rrign=rign; *rarea=area; *rflux=flux; return(flag); } /*****************************************************************************/ fitsh-0.9.2/src/fiinfo-pnm.c0000644000175000017500000002405512771507777014302 0ustar apalapal/*****************************************************************************/ /* fiinfo-pnm.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Command line user interface to get some statistics from FITS data: */ /* Dumping 2D FITS images (fitsimage: dim=2) into PGM or PPM format. */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #include "fitsh.h" #include "fitsmask.h" #include "tensor.h" #include "common.h" #include "statistics.h" #include "fiinfo.h" /*********************************************************/ /* Old histeq */ /* f=fmin;n=fmax-fmin; while ( n ) { if ( w>rawdata[f+n/2] ) f+=n/2+1,n-=n/2+1; else n=n/2; }; d=(double)(f-fmin)/(double)(fmax-fmin); contrast=0.1; slope=4.0; d=2*d-1.0; d=(((contrast-1.5+0.5*slope)*d*d+(-2.0*contrast+2.5- 0.5*slope))*d*d+contrast)*d; d=(d+1.0)/2.0; ******************************************************************************/ #define HISTEQBIN 256 typedef struct { double cnt; double lower,upper,width,area; double finalupper; } histodata; int fitsimage_dump_pnm(fitsimage *img,char **mask,FILE *fw,pnmparam *pp) { double *rawdata,dmin,dmax,d,w,am[2][2],bv[2],x,y, pmin,pmax,det,slope,contrast; int sx,sy,i,j,n,f,np,is_first,lp,lsize,fsp,nh,wi,wj; unsigned char *line; char **fsmask; histodata *hd; if ( img==NULL || img->data==NULL ) return(1); sx=img->sx,sy=img->sy; if ( sx<=0 || sy<=0 ) return(1); if ( ! pp->is_color ) fprintf(fw,"P5\n"); else fprintf(fw,"P6\n"); fprintf(fw,"%d %d\n",sx,sy); fprintf(fw,"%d\n",pp->is_16bit?65535:255); np=0;is_first=1;dmin=dmax=0.0; if ( pp->scalemethod==1 || pp->minmaxmethod==4 ) fsp=sx*sy; /* all pixels are needed by 'histeq' && 'percentage' */ else fsp=40*40; if ( fsp>sx*sy ) fsp=sx*sy; fsmask=fits_mask_create_floyd(sx,sy,10,(int)((int64_t)10*(int64_t)sx*(int64_t)sy/(int64_t)fsp),1); rawdata=malloc(sizeof(double)*fsp); for ( i=0 ; idata[i][j]; if ( is_first ) dmin=dmax=d,is_first=0; else if ( ddmax ) dmax=d; if ( ! fsmask[i][j] && npminmaxmethod ) { case MM_MINMAX: pmin=dmin, pmax=dmax; break; case MM_MANUAL: if ( pp->mmin_set ) pmin=pp->manmin; else pmin=dmin; if ( pp->mmax_set ) pmax=pp->manmax; else pmax=dmax; break; case MM_ZSCALE: case MM_ZMIN: case MM_ZMAX: am[0][0]=am[0][1]=am[1][0]=am[1][1]=0.0; bv[0]=bv[1]=0.0; for ( i=np/4,lp=0 ; i<3*np/4 ; i++ ) { x=(double)(i-np/2); y=rawdata[i]; am[0][0]+=x*x; am[0][1]+=x; am[1][1]+=1.0; bv[0]+=x*y; bv[1]+=y; lp++; } am[1][0]=am[0][1]; det=am[0][0]*am[1][1]-am[1][0]*am[0][1]; slope=(+am[1][1]*bv[0]-am[0][1]*bv[1])/det; if ( pp->zcontrast>0.0 ) contrast=pp->zcontrast; else contrast=0.25; pmin=rawdata[np/2]-(slope/contrast)*(double)(np/2); pmax=rawdata[np/2]+(slope/contrast)*(double)(np/2); if ( pp->minmaxmethod==MM_ZMIN ) pmin=dmin; /* no, zmin */ if ( pp->minmaxmethod==MM_ZMAX ) pmax=dmax; /* no, zmax */ break; case MM_PERCENTAGE: /* percentage */ i=(int)((0.5-pp->percentage/200.0)*(double)np); if ( i<0 ) i=0; if ( i>=np ) i=np-1; j=(int)((0.5+pp->percentage/200.0)*(double)np); if ( j<0 ) j=0; if ( j>=np ) j=np-1; pmin=rawdata[i], pmax=rawdata[j]; break; default: pmin=dmin, pmax=dmax; break; } if ( pmax<=pmin ) pmax=pmin+1.0; if ( pp->scalemethod==SCALE_HISTEQU ) { int il,ih; double tcnt,tavg,w,tw,tt,hmin,hmax; nh=HISTEQBIN; hd=(histodata *)malloc(sizeof(histodata)*nh); tcnt=0.0;hmin=rawdata[0]; for ( i=0 ; itavg ) w=tavg; hd[i].width=w; tw+=hd[i].width; } tt=0.0; for ( i=0 ; iis_flip ) wi=i; else wi=sy-1-i; for ( j=0 ; jis_mirror ) wj=sx-1-j; else wj=j; w=img->data[wi][wj]; switch ( pp->scalemethod ) { case SCALE_LINEAR: /* linear */ d=(w-pmin)/(pmax-pmin); break; case SCALE_HISTEQU: /* histeq */ f=0;n=nh; while ( n>0 ) { if ( w>hd[f+n/2].finalupper ) f+=n/2+1,n-=n/2+1; else n=n/2; }; d=(double)f/(double)nh; break; case SCALE_LOG: /* log */ if ( 0.0 < pmin && 0.0 < w ) { d=(log(w)-log(pmin))/(log(pmax)-log(pmin)); } else if ( w<=0.0 ) d=0.0; else { d=(w-pmin)/(pmax-pmin); } break; case SCALE_SQRT: /* sqrt */ if ( 0.0 < pmin && 0.0 < w ) { d=(sqrt(w)-sqrt(pmin))/(sqrt(pmax)-sqrt(pmin)); } else if ( w<=0.0 ) d=0.0; else { d=(w-pmin)/(pmax-pmin); } break; case SCALE_SQUARED: /* squared */ if ( 0.0 < pmin && 0.0 < w ) { d=(w*w-pmin*pmin)/(pmax*pmax-pmin*pmin); } else if ( w<=0.0 ) d=0.0; else { d=(w-pmin)/(pmax-pmin); } break; default: d=(w-pmin)/(pmax-pmin); break; } d=0.5+(d-1.0+pp->brightness)*pp->contrast; if ( pp->is_invert ) d=1.0-d; if ( d<0.0 ) d=0.0; else if ( d>1.0 ) d=1.0; if ( pp->palette==NULL || pp->ncol<=0 ) { int p; if ( pp->is_16bit ) { p=(int)(d*65536.0); if ( p>=65536 ) p=65535; if ( p<0 ) p=0; if ( ! pp->is_color ) { line[lsize+0]=p>>8; line[lsize+1]=p&0xFF; lsize+=2; } else { line[lsize+0]=line[lsize+2]=line[lsize+4]=p>>8; line[lsize+1]=line[lsize+3]=line[lsize+5]=p&0xFF; lsize+=6; } } else { p=(int)(d*256.0); if ( p>=256 ) p=255; if ( p<0 ) p=0; if ( ! pp->is_color ) { line[lsize]=p; lsize++; } else { line[lsize]=line[lsize+1]=line[lsize+2]=p; lsize+=3; } } } else { int bc,r,g,b,p; gradient *pl; bc=(int)(d*(double)pp->ncol); if ( bc<0 ) bc=0; if ( bc>=pp->ncol ) bc=pp->ncol-1; d=d*(double)pp->ncol-(double)bc; if ( d<0.0 ) d=0.0; if ( d>1.0 ) d=1.0; pl=&pp->palette[bc]; r=(pl->beg.r*(1.0-d)+pl->end.r*d); g=(pl->beg.g*(1.0-d)+pl->end.g*d); b=(pl->beg.b*(1.0-d)+pl->end.b*d); if ( r<0 ) r=0; if ( 65535is_color ) { p=(r+g+b)/3; if ( pp->is_16bit ) { line[lsize+0]=p>>8; line[lsize+1]=p&0xff; lsize+=2; } else { line[lsize]=p/256; lsize++; } } else { if ( pp->is_16bit ) { line[lsize+0]=r>>8; line[lsize+1]=r&0xff; line[lsize+2]=g>>8; line[lsize+3]=g&0xff; line[lsize+4]=b>>8; line[lsize+5]=b&0xff; lsize+=6; } else { line[lsize+0]=r/256, line[lsize+1]=g/256, line[lsize+2]=b/256; lsize+=3; } } } } fwrite(line,1,lsize,fw); } if ( hd != NULL ) free(hd); if ( rawdata != NULL ) free(rawdata); if ( line != NULL ) free(line); return(0); } /*****************************************************************************/ static int hex_digit(int c) { if ( '0' <= c && c <= '9' ) return(c-'0'); else if ( 'a' <= c && c <= 'f' ) return(c-'a'+10); else if ( 'A' <= c && c <= 'F' ) return(c-'A'+10); else return(-1); } int parse_palette(char *pstr,gradient **rpal,int *rncol) { int ncol,cd,hx[12],sep,i,j,cl; gradient *pal,*pp; for ( i=0 ; i<12 ; i++ ) hx[i]=0; ncol=0;pal=NULL; while ( *pstr && *pstr != ',' ) { cd=0; while ( *pstr && *pstr != ',' && hex_digit(*pstr)>=0 && cd<12 ) { hx[cd]=hex_digit(*pstr); pstr++;cd++; }; if ( ! *pstr || *pstr==',' || *pstr==':' ) sep=0; else if ( *pstr=='/' || *pstr=='-' ) sep=1; else { if ( pal != NULL ) free(pal); return(1); } if ( *pstr && *pstr != ',' ) pstr++; if ( ! ( cd==1 || cd==3 || cd==2 || cd==6 || cd==4 || cd==12 ) ) { if ( pal != NULL ) free(pal); return(1); } pal=(gradient *)realloc(pal,sizeof(int)*6*(ncol+1)); pp=&pal[ncol]; if ( cd==1 ) { pp->beg.r=pp->beg.g=pp->beg.b=hx[0]*0x1111; } else if ( cd==3 ) { pp->beg.r=hx[0]*0x1111, pp->beg.g=hx[1]*0x1111, pp->beg.b=hx[2]*0x1111; } else if ( cd==2 ) { pp->beg.r=pp->beg.g=pp->beg.b=(hx[0]*0x10+hx[1])*0x101; } else if ( cd==6 ) { pp->beg.r=(hx[0]*0x10+hx[1])*0x101, pp->beg.g=(hx[2]*0x10+hx[3])*0x101, pp->beg.b=(hx[4]*0x10+hx[5])*0x101; } else if ( cd==4 ) { pp->beg.r=pp->beg.g=pp->beg.b=hx[0]*0x1000+hx[1]*0x100+hx[2]*0x10+hx[3]; } else if ( cd==12 ) { pp->beg.r=hx[ 0]*0x1000+hx[ 1]*0x100+hx[ 2]*0x10+hx[ 3], pp->beg.g=hx[ 4]*0x1000+hx[ 5]*0x100+hx[ 6]*0x10+hx[ 7], pp->beg.b=hx[ 8]*0x1000+hx[ 9]*0x100+hx[10]*0x10+hx[11]; } if ( ! sep ) pp->end.r=0; else pp->end.r=1; pp->end.g=pp->end.b=0; ncol++; }; if ( ncol>0 ) pal[ncol-1].end.r=-1; else { if ( pal != NULL ) free(pal); return(1); } for ( i=0,j=0,cl=0 ; i #include #include #include #include #include #include #include #include "longhelp.h" #include "fitsh.h" #include "fitsmask.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "io/format.h" #include "fbase.h" #include "math/spline/bicubic.h" #include "math/spline/spline.h" #include "statistics.h" #include "transform.h" #include "tensor.h" #include "common.h" #include "weight.h" #include "history.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ typedef struct { fits *img; char **mask; double time; } stack; #define MODE_MEAN 1 #define MODE_MEDIAN 2 int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int fprint_fic_mpstack_usage(FILE *fw) { fprintf(fw, "Usage:\tfic_mpstack [-h|--help] [-C|--comment] [-V|--verbose]\n" "\t[-i|--input-list ] [-m|--mode {mean|median}]\n" "\t[-c|--input-coefficients ]\n" "\t-f|--offset , -s|--size ,\n"); return(0); } longhelp_entry fic_mpstack_long_help[]= { LONGHELP_OPTIONS, { "General options:", NULL }, { "-h, --help", "Gives general summary about the command line options." }, { "--long-help", "Gives a detailed list of command line options." }, { "--version", "Gives some version information about the program." }, { NULL, NULL } }; int fprint_fic_mpstack_long_help(FILE *fw) { fprintf(fw, "Usage:\tfic_mpstack --input-list --input-coefficients \n" "The main purpose of this program is to perform a special kind of \n" "4 dimensional transformation and image stacking that aids faint minor planet \n" "searches.\n"); fprintf(fw,"\n"); longhelp_fprint(fw,fic_mpstack_long_help,0,-1); fprintf(fw,"\n"); fprintf(fw,"Report bugs to <%s>\n",FITSH_MAINT_EMAIL); return(0); } /*****************************************************************************/ int main(int argc,char *argv[]) { FILE *fr,*fw; int i,is_help; char *inlistfile,*incoefffile,*modestr; int ofx,ofy,nsx,nsy,tsx,tsy; int mode; stack *images; int nimage; progbasename=strrchr(argv[0],'/'); if ( progbasename != NULL ) progbasename++; else progbasename=argv[0]; inlistfile=incoefffile=NULL; is_comment=is_verbose=is_help=0; ofx=ofy=nsx=nsy=0; /* input list format: [1] filename [2] time offset (usually in days) */ /* input coefficient format [1] Order [2] x' [3] x'' [4] y' [5] y'' [6] output filename */ modestr=NULL; i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS, "--version:%NS-1f%q",&is_help, "--version-short|--short-version:%NS-2f%q",&is_help, "--long-help|--help-long:%SN2f%q",&is_help, "-V|--verbose:%f",&is_verbose, "-h|--help:%f%q",&is_help, "-i|--input-list:%s",&inlistfile, "-c|--input-coefficients:%s",&incoefffile, "-f|--offset:%d,%d",&ofx,&ofy, "-s|--size:%d,%d",&nsx,&nsy, "-m|--mode:%s",&modestr, "*:%e", NULL); if ( i ) { fprint_error("invalid command line argument near '%s'",argv[i]); return(1); } else if ( is_help<0 ) { fprint_generic_version(stdout,argv[0],"fic_mpstack",FITSH_FIC_MPSTACK_VERSION,is_help); return(0); } else if ( is_help>1 ) { fprint_fic_mpstack_long_help(stdout); return(0); } else if ( is_help ) { fprint_fic_mpstack_usage(stdout); return(0); } if ( modestr ) { if ( strcmp(modestr,"mean")==0 ) mode=MODE_MEAN; else if ( strcmp(modestr,"median")==0 ) mode=MODE_MEDIAN; else { fprint_error("invalid mode '%s'",modestr); return(1); } } else mode=MODE_MEDIAN; if ( inlistfile==NULL || strcmp(inlistfile,"-")==0 ) fr=stdin; else if ( (fr=fopen(inlistfile,"rb"))==NULL ) { fprint_error("unable to open input list file '%s'",inlistfile); return(1); } nimage=0; images=NULL; tsx=tsy=0; while ( ! feof(fr) ) { char buff[256],*cmd[16]; int n,i; FILE *ff; if ( fgets(buff,256,fr)==NULL ) break; buff[255]=0; for ( i=0 ; buff[i] ; i++ ) { if ( buff[i]=='#' ) { buff[i]=0; break; } } n=tokenize_spaces(buff,cmd,16); if ( n<2 ) continue; ff=fopen(cmd[0],"rb"); if ( ff==NULL ) { fprint_error("unable to open input file '%s'",cmd[0]); return(1); } images=(stack *)realloc(images,sizeof(stack)*(nimage+1)); if ( (images[nimage].img=fits_read(ff))==NULL ) { fprint_error("unable to interpret data from file '%s' as FITS data",cmd[0]); return(1); } else if ( images[nimage].img->i.dim != 2 ) { fprint_error("image dimension from file '%s' differs from 2",cmd[0]); return(1); } if ( nimage==0 ) { tsx=images[nimage].img->i.sx; tsy=images[nimage].img->i.sy; } else if ( tsx != images[nimage].img->i.sx || tsy != images[nimage].img->i.sy ) { fprint_error("FITS data '%s' has different size",cmd[0]); return(1); } fits_rescale(images[nimage].img); if ( sscanf(cmd[1],"%lg",&images[nimage].time)<1 ) { fprint_error("unable to interpret '%s' as time stamp",buff[1]); return(1); } images[nimage].mask=fits_mask_read_from_header(&images[nimage].img->header,tsx,tsy,NULL); fclose(ff); nimage++; } fclose(fr); if ( ! ( 0i.bit=-32; out->i.curr.bscale=1.0; out->i.curr.bzero=0.0; fits_alloc_image(out,nsx,nsy); mask=fits_mask_create_empty(nsx,nsy); for ( k=0 ; ktime; for ( o=0 ; otime; } idx[k]=(int)floor(dx); idy[k]=(int)floor(dy); adx=dx-floor(dx); ady=dy-floor(dy); cxy[4*k+0]=(1-adx)*(1-ady); cxy[4*k+1]=( adx )*(1-ady); cxy[4*k+2]=(1-adx)*( ady ); cxy[4*k+3]=( adx )*( ady ); } for ( i=0 ; imask[iy][ix] || s->mask[iy][ix+1] || s->mask[iy+1][ix] || s->mask[iy+1][ix+1] ) continue; v=s->img->i.data[iy ][ix ]*cxy[4*k+0]+ s->img->i.data[iy ][ix+1]*cxy[4*k+1]+ s->img->i.data[iy+1][ix ]*cxy[4*k+2]+ s->img->i.data[iy+1][ix+1]*cxy[4*k+3]; sp+=v; arr[np]=v; np++; } if ( 0i.data[i][j]=(mode==MODE_MEAN?sp/np:median(arr,np)); else { out->i.data[i][j]=0.0; mask[i][j]=MASK_OUTER; } } } out->i.read.bscale=1.0, out->i.read.bzero=0.0; fits_set_image_params(out); fits_backscale(out,out->i.read.bscale,out->i.read.bzero); fits_history_export_command_line(out,"fic_mpstack",FITSH_FIC_MPSTACK_VERSION,argc,argv); fits_mask_export_as_header(&out->header,1,mask,nsx,nsy,NULL); if ( outfile==NULL ) fw=stdout; else fw=fopenwrite(outfile); if ( fw==NULL ) { fprint_error("unable to create output image file '%s'",outfile); return(1); } fits_write(fw,out); fclosewrite(fw); fits_mask_free(mask); fits_free(out); free(cxy); free(idy); free(idx); free(arr); gettimeofday(&tv1,NULL); tv1.tv_usec -= tv0.tv_usec; tv1.tv_sec -= tv0.tv_sec; if ( tv1.tv_usec < 0 ) { tv1.tv_usec += 1000000; tv1.tv_sec -= 1; } if ( is_verbose ) fprintf(stderr,"%s: done: %d.%.6d\n",outfile,(int)tv1.tv_sec,(int)tv1.tv_usec); } return(0); } /*****************************************************************************/ fitsh-0.9.2/src/firandom-eval.c0000644000175000017500000003040012771247761014745 0ustar apalapal/*****************************************************************************/ /* firandom-eval.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* User-interface functions for firandom: parsing and evaluating of command */ /* line expressions (for background /-m/ and starlist /-l/ */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "fitsh.h" #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "math/fit/lmfit.h" #include "math/expint/expint.h" #include "math/point.h" #include "psn/psn-general.h" #include "tensor.h" #include "common.h" #include "stars.h" #include "firandom.h" psnsym defvarnames[]= { { T_VAR, VAR_X , "x" }, /* scaled x coordinate */ { T_VAR, VAR_Y , "y" }, /* scaled y coordinate */ { T_VAR, VAR_AX , "X" }, /* abs. x coordinate ( 0<=Xdata==NULL ) return(1); sx=img->sx,sy=img->sy; if ( bgarg==NULL ) { for ( i=0 ; idata[i][j]=0.0; } } return(0); } else { bg=get_background_psn(bgarg); if ( bg==NULL ) return(1); izoom=1.0/(double)zoom; zintm=izoom*izoom; for ( i=0 ; i0.0 ) n=get_gaussian(0.0,stddev); /* extra noise */ else n=0.0; img->data[i][j]=(w+n)*zintm; } } return(0); } } /*****************************************************************************/ int fep_to_sdk(double f,double e,double p,double *s,double *d,double *k) { *s=f/SIG_FWHM; *d=(*s)*e/(2-e)*cos(2.0*p*M_PI/180.0); *k=(*s)*e/(2-e)*sin(2.0*p*M_PI/180.0); return(0); } int sdk_to_fep(double s,double d,double k,double *f,double *e,double *p) { double m; *f=s*SIG_FWHM; m=sqrt(d*d+k*k); *e=1-(s-m)/(s+m); *p=0.5*180.0/M_PI*atan2(k,d); return(0); } int sdk_to_isdk(double s,double d,double k,double *is,double *id,double *ik) { double idet2,s2,m2; s2=s*s; m2=d*d+k*k; idet2=1.0/((s2-m2)*(s2-m2)); *is=(s+m2)*idet2; *id=-2*s*d*idet2; *ik=-2*s*k*idet2; return(0); } int isdk_to_sdk(double is,double id,double ik,double *s,double *d,double *k) { double det; det=is*is-id*id-ik*ik; *s=sqrt(0.5*(is+sqrt(det))/det); *d=-id/(2*(*s)*det); *k=-ik/(2*(*s)*det); return(0); } /*****************************************************************************/ int replace_limiters(char *buff) { int i,in_sl,in_pa,n; in_sl=in_pa=0; remove_spaces(buff); n=strlen(buff); for ( i=0 ; i=1 ) return(1); else in_sl++; } else if ( buff[i]==']' ) { if ( in_sl<=0 ) return(1); else in_sl--; } else if ( buff[i]=='(' ) in_pa++; else if ( buff[i]==')' ) { if ( in_pa<=0 ) return(1); else in_pa--; } else if ( buff[i]==',' || buff[i]==';' ) { if ( ! in_sl && ! in_pa ) buff[i]='|'; else if ( in_sl && ! in_pa ) buff[i]=';'; else buff[i]=','; } } return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define LTYPE_MASK_INT 0x03 #define LTYPE_INT_MAG 0x01 #define LTYPE_INT_FLUX 0x02 #define LTYPE_ABS_X 0x04 #define LTYPE_ABS_Y 0x08 #define LTYPE_ABS_XY (LTYPE_ABS_X|LTYPE_ABS_Y) #define LTYPE_MASK_SHAPE 0x30 #define LTYPE_SHAPE_FEP 0x10 #define LTYPE_SHAPE_SIG 0x20 #define LTYPE_SHAPE_SDK 0x30 int create_input_list(char *buff,starlistparam *lp,star **rstars,int *rnstar,int sseed) { star *stars,*ws; int nstar; char **terms; int nterm; int i,j,k,l,n,ltype,last_set; psnsym *mysyms[6]; psn *in; double gls,gld,glk,glf,gle,glp,glis,glid,glik; double vars[32]; /* x,y,X,Y, i,m, f,e,p, s,d,k, S, D, K, n, t,u,v,w, SX,SY */ psn *exs[16]; /* x,y,X,Y, i,m, f,e,p, s,d,k, S, D, K */ mysyms[0]=psn_general_op; mysyms[1]=psn_general_fn; mysyms[2]=psn_general_fn_rnd; mysyms[3]=defvarnames; mysyms[4]=NULL; *rstars=stars=NULL; *rnstar=nstar=0; n=strlen(buff);nterm=1; for ( i=0 ; i=0 ) { if ((k&MSK_COORD)==(MSK_X |MSK_Y )) ltype|=0; else if ((k&MSK_COORD)==(MSK_AX|MSK_Y )) ltype|=LTYPE_ABS_X; else if ((k&MSK_COORD)==(MSK_X |MSK_AY)) ltype|=LTYPE_ABS_Y; else if ((k&MSK_COORD)==(MSK_AX|MSK_AY)) ltype|=LTYPE_ABS_XY; else ltype=-1; } if ( ltype>=0 ) { int m; m=0; if ( k&MSK_SH ) ltype|=LTYPE_SHAPE_FEP,m++; else if ( k&MSK_SN ) ltype|=LTYPE_SHAPE_SIG,m++; else if ( k&MSK_SI ) ltype|=LTYPE_SHAPE_SDK,m++; if ( m>1 ) ltype=-1; } if ( ltype<0 ) { free(cmd);free(terms); for ( l=0 ; lsx, vars[PARAM_SY]=(double)lp->sy; vars[PARAM_CNTR]=(double)j; for ( l=0 ; lox)/lp->scale; else lx=vars[VAR_AX]=vars[VAR_X]*lp->scale+lp->ox; if ( ltype & LTYPE_ABS_Y ) ly=vars[VAR_AY],vars[VAR_Y]=(ly-lp->oy)/lp->scale; else ly=vars[VAR_AY]=vars[VAR_Y]*lp->scale+lp->oy; if ( ! ( ltype & LTYPE_INT_MAG ) ) li=vars[VAR_I]; else li=mag_to_flux(vars[VAR_M],&lp->mf0); if ( (ltype<YPE_MASK_SHAPE)==LTYPE_SHAPE_FEP ) fep_to_sdk (vars[VAR_SH_F],vars[VAR_SH_E],vars[VAR_SH_P],&ls,&ld,&lk); else if ( (ltype<YPE_MASK_SHAPE)==LTYPE_SHAPE_SDK ) isdk_to_sdk(vars[VAR_SI_S],vars[VAR_SI_D],vars[VAR_SI_K],&ls,&ld,&lk); else ls=vars[VAR_SN_S],ld=vars[VAR_SN_D],lk=vars[VAR_SN_K]; stars=(star *)realloc(stars,sizeof(star)*(nstar+1)); ws=&stars[nstar]; ws->location.gcx=lx, ws->location.gcy=ly; ws->flux=li; ws->gsig=ls; ws->gdel=ld; ws->gkap=lk; ws->shape.model=SHAPE_ELLIPTIC; nstar++; } for ( l=0 ; l #include #include #include #include #include #include #include #include #include #include "io/iof.h" #include "io/scanarg.h" #include "io/tokenize.h" #include "cache.h" #include "statistics.h" #include "str.h" #include "longhelp.h" #include "fitsh.h" #ifdef HAVE_NO_CC_EXTENSION #define __extension__ #endif /*****************************************************************************/ #define STAT_NONE 0 #define STAT_COUNT 1 #define STAT_MEAN 2 #define STAT_MEANDEV 3 #define STAT_MIN 4 #define STAT_MAX 5 #define STAT_SUM 6 #define STAT_SUM2 7 #define STAT_PURE_CUMULATIVE 7 #define STAT_MEDIAN 8 #define STAT_MEDIANDEV 9 #define STAT_MEANMEDDEV 10 #define STAT_MEDIANMEDDEV 11 #define STAT_MODE 12 #define STAT_MODEDEV 13 #define STAT_MODEMEDDEV 14 #define STAT_RCOUNT 21 #define STAT_RMEAN 22 #define STAT_RMEANDEV 23 #define STAT_RMIN 24 #define STAT_RMAX 25 #define STAT_RSUM 26 #define STAT_RSUM2 27 #define STAT_RMEDIAN 28 #define STAT_RMEDIANDEV 29 #define STAT_RMEANMEDDEV 30 #define STAT_RMEDIANMEDDEV 31 #define STAT_RMODE 32 #define STAT_RMODEDEV 33 #define STAT_RMODEMEDDEV 34 typedef struct { char *name; int code; } dataname; static dataname datanamelist[]= { { "count", STAT_COUNT }, { "mean", STAT_MEAN }, { "average", STAT_MEAN }, { "avg", STAT_MEAN }, { "stddev", STAT_MEANDEV }, { "sigma", STAT_MEANDEV }, { "meandev", STAT_MEANDEV }, { "meanstddev", STAT_MEANDEV }, { "min", STAT_MIN }, { "max", STAT_MAX }, { "sum", STAT_SUM }, { "sum2", STAT_SUM2 }, { "median", STAT_MEDIAN }, { "mediandev", STAT_MEDIANDEV }, { "medianstddev", STAT_MEDIANDEV }, { "meanmeddev", STAT_MEANMEDDEV }, { "medianmeddev", STAT_MEDIANMEDDEV }, { "mode", STAT_MODE }, { "modedev", STAT_MODEDEV }, { "modestddev", STAT_MODEDEV }, { "modemeddev", STAT_MODEDEV }, { "rcount", STAT_RCOUNT }, { "rmean", STAT_RMEAN }, { "raverage", STAT_RMEAN }, { "ravg", STAT_RMEAN }, { "rstddev", STAT_RMEANDEV }, { "rsigma", STAT_RMEANDEV }, { "rmeandev", STAT_RMEANDEV }, { "rmeanstddev", STAT_RMEANDEV }, { "rmin", STAT_RMIN }, { "rmax", STAT_RMAX }, { "rsum", STAT_RSUM }, { "rsum2", STAT_RSUM2 }, { "rmedian", STAT_RMEDIAN }, { "rmediandev", STAT_RMEDIANDEV }, { "rmedianstddev", STAT_RMEDIANDEV }, { "rmeanmeddev", STAT_RMEANMEDDEV }, { "rmedianmeddev", STAT_RMEDIANMEDDEV }, { "rmode", STAT_RMODE }, { "rmodedev", STAT_RMODEDEV }, { "rmodestddev", STAT_RMODEDEV }, { "rmodemeddev", STAT_RMODEDEV }, { NULL, -1 } }; static int statlist_default[] = { STAT_COUNT,STAT_MEAN,STAT_MEANDEV,-1 }; /*****************************************************************************/ typedef struct { char *key; int id; } key; typedef struct lookupkey lookupkey; struct lookupkey { lookupkey *lookups; key value; }; /*****************************************************************************/ typedef struct { size_t offset; /* offset in collectbuffer->buffer */ int key; /* position of the base column */ int file; /* infiles[] array index */ char *keyptr; /* pointer to base column */ } line; typedef struct { lookupkey lk; char *buffer; size_t size,asize; line *lines; int nline; int is_comment; char **comments; int argc; char **argv; } collectbuffer; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define REJECTION_CENTER 0x03 #define REJECTION_C_NONE 0 #define REJECTION_C_MEAN 1 #define REJECTION_C_MEDIAN 2 #define REJECTION_C_MODE 3 #define REJECTION_MAGNITUDE 0x0C #define REJECTION_M_STDDEV 0 #define REJECTION_M_MEDDEV 4 #define REJECTION_M_ABSOLUTE 8 typedef struct { int center; double magnitude; int iterations; } rejection; typedef struct { int index; rejection r; } column; typedef struct { int id; int flag; } tmpvaluecommon; typedef struct { char *key; int id; int count; } statfieldcommon; #define N_CENTER 3 /* mean, median, mode */ #define C_MEAN 0 #define C_MEDIAN 1 #define C_MODE 2 #define N_DEVIATION 3 /* std, med, abs */ #define D_STD 0 #define D_MED 1 #define D_ABS 2 typedef struct { double center[N_CENTER]; double deviation[N_CENTER][N_DEVIATION]; } cendev; typedef struct { int count; double sum,sum2,min,max; } bcumul; typedef struct { double sum,sum2,min,max; /* cumulative */ double median,mediandev; /* normal non-cumulative 1) */ double meanmeddev,medianmeddev; /* normal non-cumulative 2) */ double mode,modedev,modemeddev; /* normal non-cumulative 3) */ int rcount; /* rej'd non-cumulative 1) */ double rsum,rsum2,rmin,rmax; /* rej'd non-cumulative 2) */ double rmedian,rmediandev; /* rej'd non-cumulative 3) */ double rmeanmeddev,rmedianmeddev; /* rej'd non-cumulative 4) */ double rmode,rmodedev,rmodemeddev; /* rej'd non-cumulative 5) */ } statfielddata; typedef struct { bcumul nb; cendev nc; bcumul rb; cendev rc; } statfielddata2; typedef struct { lookupkey lk; /* hash tree for cumulative stat's */ void *fields; /* keys */ int nfield,afield; /* number of keys (+ alloc'ed) */ char *tmptemplate; /* template name of temporary file */ int fh; /* file handle of the temporary file */ int nstat; /* number of columns for making stat */ column *colstats; /* column spec info (for rejection) */ void *tmps; /* list of temporary values, cached */ size_t ntmp; /* number of temporary values. */ size_t atmp; /* number of allocated entries (tmp) */ off_t wtmp; /* num of written temp entries */ size_t mxtmp; /* max number of temporary values */ size_t maxmem; /* max memory in bytes */ } collectstat; /*****************************************************************************/ int is_verbose,is_comment; char *progbasename; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fprint_error(char *expr,...) { va_list ap; fprintf(stderr,"%s: error: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } int fprint_warning(char *expr,...) { va_list ap; fprintf(stderr,"%s: warning: ",progbasename); va_start(ap,expr); vfprintf(stderr,expr,ap); va_end(ap); fprintf(stderr,"\n"); return(0); } /*****************************************************************************/ int *get_stat_list(char *statstr) { char *wstr,*cmd[16]; int i,n,*ret,j; wstr=strdup(statstr); n=tokenize_char(statstr,cmd,',',15); if ( n <= 0 ) { free(wstr); return(NULL); } ret=(int *)malloc(sizeof(int)*(n+1)); for ( i=0 ; i>4) & 0x0f; else k=(w>>0) & 0x0f; #elif HASH_BITS == 2 int w; w=(unsigned char)kstr[offset/4]; k=(w>>(2*(3-(offset%4)))) & 0x03; #elif HASH_BITS == 1 int w; w=(unsigned char)kstr[offset/8]; k=(w>>(7-(offset%8))) & 0x01; #else #error "Invalid hash bit value" #endif return(k); } int lookup_get_end(char *kstr,int offset) { int k; #if HASH_BITS == 8 k=(unsigned char)kstr[offset]; #elif HASH_BITS == 4 k=(unsigned char)kstr[offset/2]; #elif HASH_BITS == 2 k=(unsigned char)kstr[offset/4]; #elif HASH_BITS == 1 k=(unsigned char)kstr[offset/8]; #else #error "Invalid hash bit value" #endif return(k); } key * lookup_search_or_add_key(lookupkey *lk,char *kstr,int offset) { int k,w,o; key *ret,tmp; char *wkey; lookupkey *wl; k=lookup_get_hash_bit(kstr,offset); if ( lk->lookups==NULL ) /* empty set */ { lk->lookups=(lookupkey *)malloc(sizeof(lookupkey)*(1<lookups,0,sizeof(lookupkey)*(1<lookups[k].lookups=NULL; lk->lookups[k].value.key=strdup(kstr); ret=&lk->lookups[k].value; } else if ( lk->lookups[k].lookups != NULL ) { ret=lookup_search_or_add_key(&lk->lookups[k],kstr,offset+1); } else if ( lk->lookups[k].value.key==NULL ) { lk->lookups[k].value.key=strdup(kstr); ret=&lk->lookups[k].value; } else if ( strcmp(lk->lookups[k].value.key,kstr)==0 ) { ret=&lk->lookups[k].value; } else { wkey=lk->lookups[k].value.key; memcpy(&tmp,&lk->lookups[k].value,sizeof(key)); memset(&lk->lookups[k].value,0,sizeof(key)); wl=&lk->lookups[k]; for ( o=offset+1,ret=NULL ; lookup_get_end(wkey,o) || lookup_get_end(kstr,o) ; o++ ) { wl->lookups=(lookupkey *)malloc(sizeof(lookupkey)*(1<lookups,0,sizeof(lookupkey)*(1<lookups[k]; else { memcpy(&wl->lookups[w].value,&tmp,sizeof(key)); wl->lookups[k].value.key=strdup(kstr); ret=&wl->lookups[k].value; break; } } } return(ret); } int lookup_free_node(lookupkey *lk) { int i; lookupkey *wl; if ( lk==NULL || lk->lookups==NULL ) return(0); for ( i=0 ; i<(1<lookups[i]; if ( wl->lookups != NULL ) lookup_free_node(wl); else if ( wl->value.key != 0 ) free(wl->value.key); } free(lk->lookups); return(0); } /****************************************************************************** int lookup_dump(FILE *fw,lookupkey *lk,int depth) { int i,j; if ( lk==NULL || lk->lookups==NULL ) return(0); for ( i=0 ; i<256 ; i++ ) { if ( lk->lookups[i].value.key != NULL ) { for ( j=0 ; jlookups[i].value.key); } else if ( lk->lookups[i].lookups != NULL ) lookup_dump(fw,&lk->lookups[i],depth+1); } return(0); } int lookup_test(void) { lookupkey lk; memset(&lk,0,sizeof(lookupkey)); lookup_search_or_add_key(&lk,"B1",0); lookup_search_or_add_key(&lk,"B2",0); lookup_search_or_add_key(&lk,"A2",0); lookup_search_or_add_key(&lk,"B2c",0); lookup_dump(stderr,&lk,0); return(0); } ******************************************************************************/ /*****************************************************************************/ int fprint_grcollect_usage(FILE *fw) { fprintf(fw, "Usage:\tgrcollect [-h|--help|--long-help|--wiki-help] [--version[-short]]\n" "\t[-V|--verbose]\n" "Options for data collection and transposition:\n" "\t [ ...] -c|--col-base <> [-t|--tmpdir ]\n" "\t{-b|--basename |-x|--extension -p|--prefix

}\n"
"\t[--rejection column=,{mean|median|mode},\n"
"\t             {stddev|meddev|absolute}=,[comment|exclude]]\n"
"\t[-a|--pre-allocate [,]\n"
"\t[-C|--comment] [-S|--additional-comment <...> [-S ...]]\n");
 fprintf(fw,
"Options for cumulative statistics:\n"
"\t [...] -c|--col-base <> -d|--col-stat <>[,...] -o|--output \n"
"\t[--stat [r]count,[r]{mean|median|mode}[[med|std]dev],\n"
"\t        [r]sum,[r]sum2,[r]min,[r]max]\n"
"\t[--rejection column=,iterations=,{mean|median|mode},\n"
"\t             {stddev|meddev|absolute}=] [--rejection ...]\n");
 fprintf(fw,
"Other options:\n"
"\t[-t|--tmpdir ]\n"
"\t[-l|--line-size ] [-m|--max-memory ]\n");
 fprintf(fw,
"Notes:\n"
" - the default directory for tempoary files is always the current one (which\n"
"   is equivalent to define `--tmpdir ./`);\n"
" - the suffixes 'k', 'm' or 'g' can be added after the amount of max. memory,\n"
"   however, this amount is only a hint, the actual usage depends on the data\n"
"   (the default value of max. memory is %d megabytes)\n",DEFAULT_MAX_MEMORY);

 return(0);
}

longhelp_entry grcollect_long_help[] = 
{
 LONGHELP_OPTIONS,

 { "General options:", NULL },
 { "-h, --help",
	"Give general summary about the command line options." },
 { "--long-help, --help-long",
        "Gives a detailed list of command line options." },
 { "--wiki-help, --help-wiki, --mediawiki-help, --help-mediawiki",
        "Gives a detailed list of command line options in Mediawiki format." },
 { "--version, --version-short, --short-version",
	"Give some version information about the program." },

 { " [,, ...]",
	"Name of the input file. At least, one file should be specified. "
	"Reading from standard input can be forced using a single dash \"-\" "
	"as input file name. More dashes are silently ignored." },
 { "-c, --col-base ",
	"Column index for the key." },

 { "Data transposition specific options:", NULL },
 { "-b, --basename ",
	"Base name of the output files. The base name string should conatain "
	"at least one \"%b\" tag, which is replaced by the respective key "
	"string on the creation of the file." },
 { "-x, --extension , -p, --prefix ",
	__extension__
	"Equivalent to \"-b|--basename %b.\". Note that "
	"in practice,  might be some sort of directory name and extension is "
	"a regular file extension, but the above substitution is done literally. "
	"Therefore, the \"dot\" between the key and the  is always "
	"inserted in the final name of the output files but a trailing "
	"slash is required at the end of  if the files are to be "
	"created in that particular directory. Note also that this case, the target "
	"directory must exist before the invocation of `grcollect`, otherwise "
	"the output files cannot be created. " },
 { "-C, --comment",
	"Insert a commented line (starting with \"#\") containing information "
	"about the version and command line invocation syntax of `grcollect` "
	"to the beginning of the transposed files." },
 { "-S, --additional-comment <...>",
	"Insert an additional commented lines (starting with \"#\") "
	"to the beginning of the transposed files." },

 { "Options for cumulative statistics:", NULL },
 { "-d, --col-stat <>[,...]",
	"Comma-separated list of column indices on which the statistics are "
	"to be calculated. Columns with non-numerical contents are ignored." 
	"Note that this option imply the cumulative statistics mode of "
	"`grcollect`." },
 { "-o, --output ",
	"The name of the output file to which the output statistics are "
	"written. The total number of columns in this file will be "
	"1+C*N, where C is the number of columns (see -d|--col-stat) "
	"on which the statistics are calculated and N is the number of "
	"statistic quantities (see --stat). The first column in the output "	
	"file is the key, which is followed by the per-column list of statistics, "
	"in the same order as the user defined after -d|--col-stat and "
	"--stat." },
 { "-s, --stat ",
	"Comma-separated list of statistics to be estimated on the input data. "
	"These can be one or more of the following:" },
 { "count",
	"Total number of records, for the given key." },
 { "rcount",
	"The number of records after rejecting outliers (i.e. it is always "
	"the same as the \"count\" value if no \"--rejection\" was used). " },
 { "mean, median, mode",
	"Mean, median or mode statistics of the data." },
 { "rmean, rmedian, rmode",
	"Mean, median or mode, after rejecting outliers." },
 { "{mean|median|mode}stddev, {mean|median|mode}meddev, stddev",
	"Scatter of the data around the mean, median or mode. The scatter can "
	"either be standard deviation (stddev) or median deviance (meddev). "
	"The literal \"stddev\" is the classic standard deviation, "
	"equivalent to \"meanstddev\". " },
 { "r{mean|median|mode}stddev, r{mean|median|mode}meddev, rstddev",
	"The same scatters as above but after rejecting outliers." },
 { "sum, rsum",
	"Sum of the data, esp. total sum and sum after rejecting outliers." },
 { "sum2, rsum2",
	"Sum of the squares, total and after rejecting outliers." },
 { "min, max",
	"Minimal and maximal data values." },
 { "rmin, rmax",
	"Minimal and maximal data values after the rejection of outliers." },

 { "-r, --rejection column=,",
	"Comma-separated directives for outlier rejection for the "
	"specified column. The rejection parameters are:" },
 { "iterations=",
	"Maximum number of iterations to reject outliers." },
 { "mean, median, mode",
	"Use the mean, median or mode for the center of the rejection." },
 { "stddev, meddev, absolute=",
	"Use the standard deviation or median deviance  "
	"for rejection limit units or define an absolute limit for "
	"rejection level." },

 { "Note that each column can have different kind of rejection method, thus "
   "more than one \"--rejection ...\" command line option can be used at "
   "the invocation of `grcollect`.", NULL }, {"", NULL },
 
 { "Other options:", NULL },
 { "-m, --max-memory [kmg]",
	__extension__
	"Maximum amount of memory available for `grcollect`. The prefixes "
	"\"k\", \"m\" or \"g\" can be used for kilobytes, megabytes and "
	"gigabytes, respectively. On 32bit systems, the maximum memory is "
	"limited to 3gigabytes. Note that `grcollect` does not use any "
	"kind of operating system specific methods to determine the maximum "
	"amount of memory, it always should be set by the user. The default "
	"value of 8 megabytes is somewhat small, so upon massive data "
	"transposition (tens or hundreds of gigabytes), this limit is "
	"worth to be set accordingly to the physical memory available. " },
 { "-t, --tmpdir ",
	"Directory for temporary file storage. Note that the default "
	"temporary directory is always the current one (which is "
	"is equivalent to define \"--tmpdir ./\"), since in a usual "
	"configuration the /tmp directory is small, moreover, it can be "
	"some sort of \"tmpfs\", temporary file system mount on the "
	"physical memory itself. " },

 { NULL, NULL }
};

int fprint_grcollect_long_help(FILE *fw,int is_wiki)
{ 
 char	*synopsis=
	"grcollect [options]  [...] [-o |-b ]";
 char	*description=
	__extension__
	"The main purpose of the program `grcollect` is twofold. First, it is intended "
	"to do data transposition on the input data, i.e. the input (which is read "
	"from files or standard input) is sorted and splitted to separate files where "
	"the splitting is based on a respective key. These keys are taken from "
	"the input data. In such a case where the input is from more files and each "
	"key is unique in a given file, this process is called data transposition "
	"(since it is similar when a 2 dimensional data matrix is stored in the form "
	"as each row is in a separate file, and one intends to transpose the matrix, "
	"i.e. store each column in a separate file). "
	"The other feature of `grcollect` is to do some sort of statistics on data "
	"associated to different keys. These statistics include average (mean, median, "
	"mode) and scatter (standard deviation or median deviance) estimations with "
	"the optional deselection of outlier points, summation, count statistics and "
	"so on.";

 fprint_generic_long_help(fw,is_wiki,grcollect_long_help,synopsis,description);

 return(0);
}

/*****************************************************************************/

int collect_buffer_reset(collectbuffer *cb)
{

 cb->buffer=NULL;
 cb->size=(size_t)0;
 cb->asize=(size_t)0;
 cb->lines=NULL;
 cb->nline=0;
 return(0);
}
int collect_buffer_free(collectbuffer *cb)
{
 if ( cb->buffer != NULL )	free(cb->buffer);
 if ( cb->lines != NULL )	free(cb->lines);
 collect_buffer_reset(cb);
 return(0);
}

int get_column_position(char *line,int col)
{
 int	pos;

 pos=0;
 while ( isspace((int)*line) )	line++,pos++;
 if ( ! (*line) )		return(-1);
 while ( col>0 )
  {	while ( ! isspace((int)*line) && *line )	line++,pos++;
	while ( isspace((int)*line) )			line++,pos++;
	if ( ! (*line) )				return(-1);
	col--;
  }
 return(pos);
}
int compare_line_by_keyptr(const void *vl1,const void *vl2)
{
 line	*l1=(line *)vl1;
 line	*l2=(line *)vl2;
 return(strcmp(l1->keyptr,l2->keyptr));
}

#define		BUFFSIZE	256

int append_string(char **rbuff,int *rsize,int *rasize,char *str,int len)
{
 if ( str==NULL )	return(0);

 if ( *rsize+len > *rasize )
  {	while ( *rsize+len > *rasize )	(*rasize)+=BUFFSIZE;
	*rbuff=(char *)realloc(*rbuff,*rasize);
  }
 memcpy((*rbuff)+(*rsize),str,len);
 (*rsize)+=len;
 return(len);
}

char *expand_basename(char *basename,char *key)
{
 char	*out;
 int	size,asize,klen,i;

 asize=size=0;
 out=NULL;

 if ( key != NULL )	klen=strlen(key);
 else			klen=0;

 if ( klen>0 )		/* ugly, very ugly, suxx */
  {	for ( i=0 ; inline ; i++ )
  {	wl=&cb->lines[i];
	wl->keyptr=cb->buffer+wl->offset+(size_t)wl->key;
  }
 qsort(cb->lines,cb->nline,sizeof(line),compare_line_by_keyptr);

 prevfile=NULL;
 fw=NULL;
 for ( i=0 ; inline ; i++ )
  {	wl=&cb->lines[i];
	filename=expand_basename(basename,wl->keyptr);
	if ( ( prevfile != NULL && strcmp(prevfile,filename) ) || prevfile==NULL || fw==NULL )
	 {	if ( fw != NULL )	fclose(fw);
		wk=lookup_search_or_add_key(&cb->lk,filename,0);
		if ( wk->id <= 0 )
		 {	fw=fopen(filename,"wb");
			wk->id=1;
		 }
		else
			fw=fopen(filename,"ab");
	 }
	if ( fw != NULL )	fprintf(fw,"%s\n",cb->buffer+wl->offset);

	if ( prevfile != NULL )		free(prevfile);
	prevfile=filename;
  }

 if ( prevfile != NULL )	free(prevfile);
 if ( fw != NULL )		fclose(fw);

 collect_buffer_free(cb);

 return(0);
}
*/

/*****************************************************************************/

#define	HPRINT_BUFFER_SIZE		256

int hprintf(int handle,char *msg,...)
{
 char		buff[HPRINT_BUFFER_SIZE],*tbuff;
 va_list	ap;
 int		n;

 va_start(ap,msg);
 n=vsnprintf(buff,HPRINT_BUFFER_SIZE,msg,ap);
 va_end(ap);
 if ( nnline ; i++ )
  {	wl=&cb->lines[i];
	wl->keyptr=cb->buffer+wl->offset+(size_t)wl->key;
  }
 qsort(cb->lines,cb->nline,sizeof(line),compare_line_by_keyptr);

 prevfile=NULL;
 fd=-1;
 pincr=NULL;

 for ( i=0 ; inline ; i++ )
  {	
	wl=&cb->lines[i];
	filename=expand_basename(basename,wl->keyptr);

	if ( ( prevfile != NULL && strcmp(prevfile,filename) ) || prevfile==NULL || fd<0 )
	 {	if ( fd >= 0 )
		 {	close(fd);
			fd=-1;
		 }

		wk=lookup_search_or_add_key(&cb->lk,filename,0);

		if ( wk->id <= 0 )
		 {	fd=open(filename,O_CREAT|O_TRUNC|O_RDWR,0666);
			if ( cb->is_comment>=1 )
			 {	hprintf(fd,"# Created by grcollect %s (fi: %s)\n",FITSH_GRCOLLECT_VERSION,FITSH_VERSION);	}
			if ( cb->is_comment>=2 )
			 {	hprintf(fd,"# Invoked command:");
				for ( j=0 ; jargc ; j++ )
				 {	if ( is_any_nasty_char(cb->argv[j]) )
						hprintf(fd," \"%s\"",cb->argv[j]);
					else
						hprintf(fd," %s",cb->argv[j]);
				 }
				hprintf(fd,"\n");
			 }
			for ( j=0 ; cb->comments != NULL && cb->comments[j] != NULL ; j++ )
			 {	cline=cb->comments[j];
				hprintf(fd,"# %s\n",cline);
			 }			
			wk->id=0;
			if ( preallocate>0 )
			 {	char	*buff;
				int	i,pagesize;
				off_t	size;
#ifdef	HOST_WIN32
				pagesize=4096;
#else
				pagesize=getpagesize();
#endif
				buff=(char *)malloc((size_t)pagesize);
				for ( i=0 ; i0 )
				 {	if ( size>(off_t)pagesize )
						i=pagesize;
					else
						i=(int)size;
					(void)write(fd,buff,i);
					size-=(off_t)i;
				 }
				free(buff);
				lseek(fd,(off_t)0,SEEK_SET);
			 }
		 }

		else
		 {	fd=open(filename,O_RDWR);
			lseek(fd,(off_t)wk->id,SEEK_SET);
		 }

		pincr=&wk->id;
	 }

	if ( fd >= 0 )
	 {	int	len;
		char	*wrbuff;
		wrbuff=cb->buffer+wl->offset;
		len=strlen(wrbuff);
		(void)write(fd,wrbuff,(size_t)len);
		(void)write(fd,"\n",(size_t)1);
		if ( pincr != NULL )
			(*pincr)+=len+1;
	 }

	if ( prevfile != NULL )		free(prevfile);

	prevfile=filename;
  }

 if ( prevfile != NULL )	free(prevfile);

 if ( fd>=0 )
	close(fd);

 collect_buffer_free(cb);

 return(0);
}

#define		FRAGSIZE	16384

int collect_read_file(collectbuffer *cb,int fid,FILE *fr,int colbase,
	char *basename,size_t maxmem,off_t preallocate)
{
 char	*buff;
 int	key,len;
 size_t	n;
 line	*wl;

 while ( ! feof(fr) )
  {	buff=freadline(fr);
	if ( buff==NULL )	break;
	remove_newlines_and_comments(buff);
	key=get_column_position(buff,colbase);
	if ( key<0 )
	 {	free(buff);
		continue;
	 }
	cb->lines=(line *)realloc(cb->lines,sizeof(line)*(cb->nline+1));
	wl=&cb->lines[cb->nline];
	cb->nline++;

	len=strlen(buff)+1;	
	if ( cb->size+(size_t)len > cb->asize )
	 {	n=(cb->size+(size_t)(len+FRAGSIZE-1))/(size_t)FRAGSIZE;
		cb->asize=(size_t)n*(size_t)FRAGSIZE;
		cb->buffer=(char *)realloc(cb->buffer,cb->asize);
	 }
	memcpy(cb->buffer+(size_t)cb->size,buff,(size_t)len);

	free(buff);

	wl->offset=cb->size;
	wl->key=key;
	wl->file=fid;
	cb->size+=(size_t)len;

	if ( cb->size > maxmem )
	 {	collect_flush(cb,basename,preallocate);		}

  };

 return(0); 
}

int collect_transposition_truncate(collectbuffer *cb,lookupkey *lk,off_t preallocate)
{
 int			i;
 lookupkey		*wl;

 if ( lk==NULL || lk->lookups==NULL )	return(0);

 for ( i=0 ; i<(1<lookups[i];
	if ( wl->lookups != NULL )
		collect_transposition_truncate(cb,wl,preallocate);	
#ifndef	HOST_WIN32
	else if ( wl->value.key != NULL )
	 {	key	*wk;
		wk=&wl->value;
		if ( (off_t)wk->id < preallocate )
			(void)truncate(wk->key,(off_t)wk->id);
	 }
#endif
  }

 return(0);
}



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

int do_transposition_normal(char **infiles,int ninfile,int colbase,
	char *basename,size_t maxmem,off_t preallocate,
	char **additionalcomments,int argc,char **argv)
{
 collectbuffer	cb; 
 FILE		*fr;
 int		i;
 
 collect_buffer_reset(&cb);
 cb.lk.lookups=NULL;
 cb.lk.value.key=NULL;
 cb.lk.value.id=0;

 cb.is_comment=is_comment;
 cb.comments=additionalcomments;
 cb.argc=argc;
 cb.argv=argv;

 for ( i=0 ; i0 )
	collect_transposition_truncate(&cb,&cb.lk,preallocate);

 lookup_free_node(&cb.lk);

 return(0);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

int compare_line_by_keyoffset(const void *vl1,const void *vl2)
{
 char	*l1=(char *)vl1;
 char	*l2=(char *)vl2;
 int	k1=(*(int *)l1)+sizeof(int);
 int	k2=(*(int *)l2)+sizeof(int);
 return(strcmp(l1+k1,l2+k2));
}

int do_transposition_cached(char **infiles,int ninfile,int colbase,
	char *basename,size_t maxmem,char *tmpdir,int linesize)
{
 FILE		*fr,*fw;
 int		i,k,l,ln,key;
 char		*tmptemplate;
 int		fh;
 char		*buff,*memcache,*p;
 int		mcline,ncline,ttline,ccline;
 char		*filename,*prevfile;

 tmptemplate=NULL; 
 strappendf(&tmptemplate,"%s/grcollect.XXXXXX",tmpdir);

/* fprintf(stderr,"do_transposition_cached(): template=%s\n",tmptemplate); */

 fh=-1;

 memcache=NULL;
 mcline=(int)(maxmem/linesize);
 ncline=0;
 ttline=0;
 
 for ( i=0 ; ilinesize-sizeof(int) )
		 {	fprint_warning("line %d in file '%s' is too long (%d rather than %d), line is truncated",ln,infiles[i],l,(int)(linesize-sizeof(int)));
			l=linesize-sizeof(int)-1;
			buff[l]=0;
		 }
		key=get_column_position(buff,colbase);
		if ( key<0 )
		 {	free(buff);
			continue;
		 }
		memcache=(char *)realloc(memcache,(size_t)(ncline+1)*(size_t)linesize);
		p=memcache+(size_t)ncline*(size_t)linesize;
		*(int *)p=key;
		memcpy(p+sizeof(int),buff,linesize-sizeof(int));
		free(buff);
		ncline++;
		ttline++;
		if ( ncline >= mcline )
		 {	if ( fh<0 )
			 {	
#ifndef	HOST_WIN32
				fh=mkstemp(tmptemplate);
#else
				mktemp(tmptemplate);
				fh=open(tmptemplate,O_CREAT|O_TRUNC|O_RDWR);
#endif
				if ( fh<0 )
				 {	fprint_error("unable to create temporary file using '%s'",tmptemplate);
					exit(1);
				 }
			 }
			qsort(memcache,ncline,linesize,compare_line_by_keyoffset);
			for ( k=0 ; k=0 && ncline>0 )
  {	qsort(memcache,ncline,linesize,compare_line_by_keyoffset);
	for ( k=0 ; k0 )
  {	if ( fh<0 )
	 	qsort(memcache,ttline,linesize,compare_line_by_keyoffset);
	else 
	 {	cache	ch;
		size_t	blocksize,membcount;
		int	multip;
	
		blocksize=cache_blocksize(linesize);
		membcount=maxmem/blocksize;
		if ( membcount<4 )	membcount=4;
		multip=1;
		while ( membcount>16384 )
		 {	multip *= 2;
			membcount /= 2;
		 }

		cache_init(&ch,linesize,(off_t)ttline,multip,(int)membcount,fh,CACHE_READ_AND_WRITE);
		cache_sort(&ch,compare_line_by_keyoffset);
		cache_finalize(&ch);
	 }
  }

 prevfile=NULL;
 fw=NULL;
 ncline=0;
 ccline=0;
 for ( i=0 ; i=0 && ccline>=ncline )
		ncline=0;

  }

 if ( prevfile != NULL )	free(prevfile);
 if ( fw != NULL )		fclose(fw);

 if ( memcache != NULL )
  {	free(memcache);
	memcache=NULL;
	ncline=0;
  }

 if ( fh>=0 )
  {	close(fh);
	unlink(tmptemplate);
	free(tmptemplate);
  }

 return(0);
}


/*****************************************************************************/

int collect_stat_reset(collectstat *cs)
{
 memset(&cs->lk,0,sizeof(lookupkey));
 cs->nfield=0;
 cs->afield=0;
 cs->fields=NULL;
 return(0);
}
int collect_stat_flush_tempfile(collectstat *cs)
{
 size_t	cw,cp,cc;

 cw=cs->ntmp*(size_t)(sizeof(tmpvaluecommon)+sizeof(double)*cs->nstat);
 for ( cp=0 ; cw>0 ; )
  {	cc=cw;
	if ( cc>16*1024*1024 )	cc=16*1024*1024;
	(void)write(cs->fh,(void *)((char *)cs->tmps+cp),cc);
	cp+=cc;
	cw-=cc;
  }

 cs->wtmp += (off_t)cs->ntmp;
 free(cs->tmps);

 cs->atmp=(size_t)0;
 cs->ntmp=(size_t)0;
 cs->tmps=NULL;

 return(0);
}

int collect_stat_read_file(collectstat *cs,FILE *fr,int colbase,column *colstats)
{
 int			mxc,i,n;
 char			*rbuff,**cmd,*kstr;
 double			*values;
 key			*wk;
 statfieldcommon	*wsc;
 statfielddata		*wsd;
 tmpvaluecommon		*wtc;
 double			*wtd;

 mxc=colbase;
 for ( i=0 ; instat ; i++ )
  {	if ( colstats[i].index>mxc )
		mxc=colstats[i].index;
  }
 mxc++;

 values=(double *)malloc(sizeof(double)*cs->nstat);

 while ( ! feof(fr) )
  {	rbuff=freadline(fr);
	if ( rbuff==NULL )	break;
	remove_newlines_and_comments(rbuff);
	cmd=tokenize_spaces_dyn(rbuff);
	if ( cmd==NULL || cmd[0]==NULL )
	 {	if ( cmd != NULL )	free(cmd);
		free(rbuff);
		continue;
	 }
	for ( n=0 ; cmd[n] != NULL ; )	n++;
	if ( nnstat ; i++ )
	 {	if ( sscanf(cmd[colstats[i].index],"%lg",&values[i])<1 )
			break;
	 }
	if ( instat )
	 {	free(cmd);
		free(rbuff);
		continue;
	 }

	kstr=cmd[colbase];
	wk=lookup_search_or_add_key(&cs->lk,kstr,0);
	if ( wk->id<=0 )
	 {	cs->nfield++;
		wk->id=cs->nfield;
		if ( cs->nfield>cs->afield )
		 {	cs->afield+=64;
			cs->fields=realloc(cs->fields,(sizeof(statfieldcommon)+sizeof(statfielddata)*cs->nstat)*cs->afield);
		 }
		wsc=(statfieldcommon *)((char *)cs->fields+(cs->nfield-1)*(sizeof(statfieldcommon)+sizeof(statfielddata)*cs->nstat));
		wsd=(statfielddata *)((char *)wsc+sizeof(statfieldcommon));
		wsc->id=wk->id;
		wsc->key=wk->key;
		wsc->count=1;
		for ( i=0 ; instat ; i++ )
		 {	wsd[i].min=wsd[i].max=values[i];
			wsd[i].sum=values[i];
			wsd[i].sum2=values[i]*values[i];
		 }
	 }
	else
	 {	wsc=(statfieldcommon *)((char *)cs->fields+(wk->id-1)*(sizeof(statfieldcommon)+sizeof(statfielddata)*cs->nstat));
		wsd=(statfielddata *)((char *)wsc+sizeof(statfieldcommon));
		for ( i=0 ; instat ; i++ )
		 {	if ( values[i]wsd[i].max )	wsd[i].max=values[i];
			wsd[i].sum+=values[i];
			wsd[i].sum2+=values[i]*values[i];
		 }
		wsc->count++;
	 }

	if ( cs->tmptemplate != NULL )
	 {	if ( cs->ntmp>=cs->atmp )
		 {	cs->atmp+=(size_t)64;
			cs->tmps=realloc(cs->tmps,(size_t)(sizeof(tmpvaluecommon)+sizeof(double)*cs->nstat)*cs->atmp);
		 }

		wtc=(tmpvaluecommon *)((char *)cs->tmps+(size_t)(sizeof(tmpvaluecommon)+sizeof(double)*cs->nstat)*cs->ntmp);
		wtd=(double *)((char *)wtc+sizeof(tmpvaluecommon));
		cs->ntmp++;
		wtc->id=wk->id;
		wtc->flag=0;
		for ( i=0 ; instat ; i++ )
		 {	wtd[i]=values[i];		}
		if ( cs->ntmp>=cs->mxtmp )
		 {	if ( cs->fh<0 )
			 {	
#ifndef	HOST_WIN32
				cs->fh=mkstemp(cs->tmptemplate);
#else
				mktemp(cs->tmptemplate);
				cs->fh=open(cs->tmptemplate,O_CREAT|O_TRUNC|O_RDWR);
#endif
				if ( cs->fh<0 )
				 {	fprint_error("unable to create temporary file using '%s'",cs->tmptemplate);
					exit(1);
				 }
			 }
			collect_stat_flush_tempfile(cs);
		 }
	 }

	free(cmd);
	free(rbuff);
  };

 return(0);
}

int collect_stat_temp_compare(const void *vt1,const void *vt2)
{
 tmpvaluecommon	*t1=(tmpvaluecommon *)vt1,
		*t2=(tmpvaluecommon *)vt2;
 if ( t1->id < t2->id )					return(-1);
 else if ( t1->id > t2->id )				return(+1);
 else if ( *(double *)(&t1[1]) < *(double *)(&t2[1]) )	return(-1);
 else if ( *(double *)(&t1[1]) > *(double *)(&t2[1]) )	return(+1);
 else							return(0);
}

int collect_stat_order_mem(collectstat *cs)
{
 int	recordsize;
 recordsize=sizeof(tmpvaluecommon)+sizeof(double)*cs->nstat;
 qsort(cs->tmps,cs->ntmp,recordsize,collect_stat_temp_compare);
 return(0);
}

int collect_stat_order_tmp(collectstat *cs)
{
 cache	ch;
 int	recordsize,multip;
 size_t	blocksize,membcount;

 recordsize=sizeof(tmpvaluecommon)+sizeof(double)*cs->nstat;

 blocksize=cache_blocksize(recordsize);
 membcount=cs->maxmem/blocksize;
 if ( membcount<4 )	membcount=4;
 multip=1;
 while ( membcount>16384 )
  {	multip *= 2;
	membcount /= 2;
  }

 cache_init(&ch,recordsize,cs->wtmp,multip,(int)membcount,cs->fh,CACHE_READ_AND_WRITE);
 cache_sort(&ch,collect_stat_temp_compare);
 cache_finalize(&ch);

 return(0);
}

int collect_stat_order(collectstat *cs)
{
 if ( cs->wtmp<=0 )	/* all data in memory, nothing written to tmpfile */
  {	collect_stat_order_mem(cs);	}
 else			/* sort tmpfile instead				  */
  {	collect_stat_order_tmp(cs);	}
 return(0);
}

double get_std_deviation(double *arr,int n,double m)
{
 int	i;
 double	s2,dev;

 if ( n<=0 || arr==NULL )	return(-1.0);
 
 s2=0.0;
 for ( i=0 ; i0.0 )	dev=sqrt(s2);
 else		dev=0.0;
 return(dev); 
}

double get_abs_deviation(double *arr,int n,double m)
{
 int	i;
 double	dev;

 if ( n<=0 || arr==NULL )	return(-1.0);
 
 dev=0.0;
 for ( i=0 ; imedian=0.5*(arr[(n-1)/2]+arr[n/2]);

 mean=wsd->sum/(double)n;

 wsd->mediandev=get_std_deviation(arr,n,wsd->median);
 wsd->medianmeddev=get_med_deviation(arr,n,wsd->median);
 wsd->meanmeddev=get_med_deviation(arr,n,mean);
 wsd->mode=2.5*wsd->median-1.5*mean;
 wsd->modedev=get_std_deviation(arr,n,wsd->mode);
 wsd->modemeddev=get_med_deviation(arr,n,wsd->mode);

 wsd->rcount=n;
 wsd->rsum=wsd->sum;
 wsd->rsum2=wsd->sum2;
 wsd->rmin=wsd->min;
 wsd->rmax=wsd->max;
 wsd->rmedian=wsd->median;
 wsd->rmediandev=wsd->mediandev;
 wsd->rmeanmeddev=wsd->meanmeddev;
 wsd->rmedianmeddev=wsd->medianmeddev;
 wsd->rmode=wsd->mode;
 wsd->rmodedev=wsd->modedev;
 wsd->rmodemeddev=wsd->modemeddev;

 lo=0;
 nn=n;

 for ( ii=0 ; r != NULL && (r->center & REJECTION_CENTER) && 
 (iiiterations || r->iterations<0) ; ii++ )
  {	rmean=wsd->rsum/(double)wsd->rcount;
	switch ( r->center & REJECTION_CENTER )
	 {   case REJECTION_C_MEAN:
		mct=rmean;
		switch ( r->center & REJECTION_MAGNITUDE )
		 {   case REJECTION_M_STDDEV:
			mdv=wsd->rsum2/(double)n-rmean*rmean;
			if ( mdv>0 )	mdv=sqrt(mdv);
			else		mdv=0.0;
			break;
		     case REJECTION_M_MEDDEV:
			mdv=wsd->rmeanmeddev;
			break;
		     case REJECTION_M_ABSOLUTE:
			mdv=1.0;
			break;
		     default:
			mdv=0.0;
			break;
		 }
		break;
	     case REJECTION_C_MEDIAN:
		mct=wsd->rmedian;
		switch ( r->center & REJECTION_MAGNITUDE )
		 {   case REJECTION_M_STDDEV:
			mdv=wsd->rmediandev;
			break;
		     case REJECTION_M_MEDDEV:
			mdv=wsd->rmedianmeddev;
			break;
		     case REJECTION_M_ABSOLUTE:
			mdv=1.0;
			break;
		     default:
			mdv=0.0;
			break;
		 }
		break;
	     case REJECTION_C_MODE:
		mct=wsd->rmode;
		switch ( r->center & REJECTION_MAGNITUDE )
		 {   case REJECTION_M_STDDEV:
			mdv=wsd->rmodedev;
			break;
		     case REJECTION_M_MEDDEV:
			mdv=wsd->rmodemeddev;
			break;
		     case REJECTION_M_ABSOLUTE:
			mdv=1.0;
			break;
		     default:
			mdv=0.0;
			break;
		 }
		break;
	     default:
		mct=0.0;
		mdv=0.0;
		break;
	 }
	if ( mdv>0.0 )
	 {	mlo=mct-mdv*r->magnitude;
		mhi=mct+mdv*r->magnitude;
		ilo=get_value_index(arr,n,mlo);
		inn=get_value_index(arr,n,mhi)-ilo;
	 }
	else
	 {	ilo=lo;
		inn=nn;
	 }
	/*
	fprintf(stderr,"mct=%12g mdv=%12g ilo=%3d inn=%3d\n",mct,mdv,ilo,inn);
	*/
	if ( inn <= 0 )
	 {	wsd->rcount=0;
		wsd->rmin=wsd->rmax=0.0;
		wsd->rsum=wsd->rsum2=0.0;
		wsd->rmedian=0.0;
		wsd->rmediandev=0.0;
		wsd->rmedianmeddev=0.0;
		wsd->rmeanmeddev=0.0;
		wsd->rmode=0.0;
		wsd->rmodedev=0.0;
		wsd->rmodemeddev=0.0;
		break;
	 }
	else if ( ilo>lo || innrcount=nn;
		wsd->rmin=arr[lo];
		wsd->rmax=arr[lo+nn-1];
		wsd->rsum=wsd->rsum2=0.0;
		for ( i=0 ; irsum+=arr[lo+i];
			wsd->rsum2+=arr[lo+i]*arr[lo+i];
		 }
		rmean=wsd->rsum/(double)wsd->rcount;
		wsd->rmedian=0.5*(arr[lo+(nn-1)/2]+arr[lo+nn/2]);

		wsd->rmediandev=get_std_deviation(arr+lo,nn,wsd->rmedian);
		wsd->rmedianmeddev=get_med_deviation(arr+lo,nn,wsd->rmedian);
		wsd->rmeanmeddev=get_med_deviation(arr+lo,nn,rmean);
		wsd->rmode=2.5*wsd->rmedian-1.5*rmean;
		wsd->rmodedev=get_std_deviation(arr+lo,nn,wsd->rmode);
		wsd->rmodemeddev=get_med_deviation(arr+lo,nn,wsd->rmode);
	 }
	else
		break;
  }

 return(0);
}

int collect_stat_non_cumulative(collectstat *cs)
{
 int			i,j,k,aa,n;
 size_t			offset;
 statfieldcommon	*wsc;
 statfielddata		*wsd;
 tmpvaluecommon		*wtc;
 double			*wtd;
 double			*arr;
 cache			ch;
 int			recordsize;

 aa=0;
 arr=NULL;

 offset=(size_t)0;

 recordsize=sizeof(tmpvaluecommon)+sizeof(double)*cs->nstat;
 if ( cs->fh>=0 )
  {	lseek(cs->fh,(off_t)0,SEEK_SET);
	cache_init(&ch,recordsize,cs->wtmp,1,4,cs->fh,CACHE_READONLY);
  }

 for ( k=0 ; knfield ; k++ )
  {	wsc=(statfieldcommon *)((char *)cs->fields+(size_t)k*(size_t)(sizeof(statfieldcommon)+sizeof(statfielddata)*cs->nstat));
	wsd=(statfielddata *)((char *)wsc+sizeof(statfieldcommon));

	n=wsc->count;
	if ( n>aa )
	 {	aa=n;
		arr=(double *)realloc(arr,sizeof(double)*aa);
	 }

	for ( i=0 ; instat ; i++ )
	 {	if ( cs->wtmp<=0 )
		 {	for ( j=0 ; jtmps+(offset+(size_t)j)*(size_t)recordsize);
				wtd=(double *)((char *)wtc+sizeof(tmpvaluecommon));
				arr[j]=wtd[i];
			 }
		 }
		else
		 {	for ( j=0 ; j0 )	median(arr,n);	/* only the first column has been ordered */

		get_noncumulative_statistics(arr,n,&wsd[i],&cs->colstats[i].r);

	 }
	offset+=(size_t)wsc->count;
  }

 if ( arr != NULL )	free(arr);

 if ( cs->fh>=0 )
	cache_finalize(&ch);

 return(0);
}

int collect_stat_write_stat_one(FILE *fw,statfieldcommon *wsc,statfielddata *wsd,int *statlist)
{
 double	mean,m2,sigma,rmean,rsigma;
 int	j,s;

 mean=wsd->sum /(double)wsc->count;
 m2  =wsd->sum2/(double)wsc->count;
 sigma=m2-mean*mean;
 if ( sigma>0.0 )	sigma=sqrt(sigma);
 else			sigma=0.0;

 if ( wsd->rcount>0 )
  {	rmean=wsd->rsum/(double)wsd->rcount;
 	m2=wsd->rsum2/(double)wsd->rcount;
	rsigma=m2-rmean*rmean;
	if ( rsigma>0.0 )	rsigma=sqrt(rsigma);
	else			rsigma=0.0;
  }
 else
  {	rmean=0.0;
	rsigma=0.0;
  }
	
 for ( j=0 ; statlist[j]>0 ; j++ )
  {	s=statlist[j];
	switch ( s )
	 {   case STAT_COUNT:
		fprintf(fw,"%6d ",wsc->count);
		break;
	     case STAT_MEAN:
		fprintf(fw,"%12g ",mean);
		break;
	     case STAT_MEANDEV:
		fprintf(fw,"%12g ",sigma);
		break;
	     case STAT_MIN:
		fprintf(fw,"%12g ",wsd->min);
		break;
	     case STAT_MAX:
		fprintf(fw,"%12g ",wsd->max);
		break;
	     case STAT_SUM:
		fprintf(fw,"%12g ",wsd->sum);
		break;
	     case STAT_SUM2:
		fprintf(fw,"%12g ",wsd->sum2);
		break;

	     case STAT_MEDIAN:
		fprintf(fw,"%12g ",wsd->median);
		break;
	     case STAT_MEDIANDEV:
		fprintf(fw,"%12g ",wsd->mediandev);
		break;
	     case STAT_MEDIANMEDDEV:
		fprintf(fw,"%12g ",wsd->medianmeddev);
		break;
	     case STAT_MEANMEDDEV:
		fprintf(fw,"%12g ",wsd->meanmeddev);
		break;
	     case STAT_MODE:
		fprintf(fw,"%12g ",wsd->mode);
		break;
	     case STAT_MODEDEV:
		fprintf(fw,"%12g ",wsd->modedev);
		break;
	     case STAT_MODEMEDDEV:
		fprintf(fw,"%12g ",wsd->modemeddev);
		break;

	     case STAT_RCOUNT:
		fprintf(fw,"%6d ",wsd->rcount);
		break;
	     case STAT_RMEAN:
		fprintf(fw,"%12g ",rmean);
		break;
	     case STAT_RMEANDEV:
		fprintf(fw,"%12g ",rsigma);
		break;
	     case STAT_RMIN:
		fprintf(fw,"%12g ",wsd->rmin);
		break;
	     case STAT_RMAX:
		fprintf(fw,"%12g ",wsd->rmax);
		break;
	     case STAT_RSUM:
		fprintf(fw,"%12g ",wsd->rsum);
		break;
	     case STAT_RSUM2:
		fprintf(fw,"%12g ",wsd->rsum2);
		break;
	     case STAT_RMEDIAN:
		fprintf(fw,"%12g ",wsd->rmedian);
		break;
	     case STAT_RMEDIANDEV:
		fprintf(fw,"%12g ",wsd->rmediandev);
		break;
	     case STAT_RMEDIANMEDDEV:
		fprintf(fw,"%12g ",wsd->rmedianmeddev);
		break;
	     case STAT_RMEANMEDDEV:
		fprintf(fw,"%12g ",wsd->rmeanmeddev);
		break;
	     case STAT_RMODE:
		fprintf(fw,"%12g ",wsd->rmode);
		break;
	     case STAT_RMODEDEV:
		fprintf(fw,"%12g ",wsd->rmodedev);
		break;
	     case STAT_RMODEMEDDEV:
		fprintf(fw,"%12g ",wsd->rmodemeddev);
		break;

	 }
  }
 return(0);
}

int collect_stat_write_stat_line(FILE *fw,
	statfieldcommon *wsc,statfielddata *wsd,int nstat,int *statlist)
{
 int	i;
 fprintf(fw,"%s\t",wsc->key);
 for ( i=0 ; ilookups==NULL )	return(0);

 for ( i=0 ; i<(1<lookups[i];
	if ( wl->lookups != NULL )
		collect_stat_write_node(fw,cs,wl,statlist);	
	else if ( wl->value.key != NULL )
	 {	wk=&wl->value;
		wsc=(statfieldcommon *)((char *)cs->fields+(wk->id-1)*(sizeof(statfieldcommon)+sizeof(statfielddata)*cs->nstat));
		wsd=(statfielddata *)((char *)wsc+sizeof(statfieldcommon));
		collect_stat_write_stat_line(fw,wsc,wsd,cs->nstat,statlist);
	 }
  }

 return(0);
}

int collect_stat_write(FILE *fw,collectstat *cs,int *statlist)
{
 collect_stat_write_node(fw,cs,&cs->lk,statlist);
 return(0);
}

int collect_stat_free(collectstat *cs)
{
 lookup_free_node(&cs->lk);
 return(0);
}


int do_collective_statistics(char **infiles,int ninfile,FILE *fw,
	int colbase,column *colstats,int ncolstat,
	int *statlist,size_t maxmem,char *tmpdir)
{
 int		i;
 int		is_non_cumulative;
 FILE		*fr;
 collectstat	cs;
 size_t		mx;

 if ( statlist==NULL )
	return(1);

 is_non_cumulative=0;
 for ( i=0 ; statlist[i]>0 && ! is_non_cumulative ; i++ )
  {	if ( statlist[i]>STAT_PURE_CUMULATIVE )
		is_non_cumulative=1;
  }

 collect_stat_reset(&cs);

 if ( is_non_cumulative )
  {	if ( tmpdir==NULL || strlen(tmpdir) <= 0 )
		cs.tmptemplate=strdup("./grcollect.XXXXXX");
	else
	 {	i=strlen(tmpdir);
		cs.tmptemplate=(char *)malloc(i+32);
		strcpy(cs.tmptemplate,tmpdir);
		if ( tmpdir[i-1] !='/' )	strcat(cs.tmptemplate,"/");
		strcat(cs.tmptemplate,"grcollect.XXXXXX");
	 }
  }
 else
	cs.tmptemplate=NULL;

 cs.tmps=NULL;
 cs.ntmp=(size_t)0;
 cs.atmp=(size_t)0;
 cs.wtmp=(off_t)0;
 mx=(maxmem/(size_t)(sizeof(tmpvaluecommon)+ncolstat*sizeof(double))+(size_t)63)/(size_t)64;
 cs.mxtmp=(size_t)64*mx;
 cs.fh=-1;
 cs.maxmem=maxmem;

 cs.nstat=ncolstat;
 cs.colstats=colstats;
 
 for ( i=0 ; i(size_t)0 && cs.fh>=0 )
	 {	collect_stat_flush_tempfile(&cs);		}
	collect_stat_order(&cs);
	collect_stat_non_cumulative(&cs);
	if ( cs.fh>=0 )
	 {	close(cs.fh);
		unlink(cs.tmptemplate);
	 }
  }

 collect_stat_write(fw,&cs,statlist);
 collect_stat_free(&cs);
 
 return(0);
}

/*****************************************************************************/

int main(int argc,char *argv[])
{
 int		i,is_help;
 int		colbase;
 char		**infiles,*basename,*extension,*tmpdir,
		*prefix,*maxmemstr,*outfile,*statstr,*colstatstr,*preallocarg,
		**rejectionlist,**additionalcomments;
 int		ninfile,*statlist;
 column		*colstats;
 int		ncolstat;
 int		linesize;
 off_t		preallocate;

 size_t		maxmem;

 progbasename=strrchr(argv[0],'/');
 if ( progbasename != NULL )	progbasename++;
 else				progbasename=argv[0];

 is_comment=0;is_verbose=is_help=0;
 additionalcomments=NULL;
 rejectionlist=NULL;

 infiles=NULL;
 outfile=basename=extension=prefix=NULL;
 statstr=maxmemstr=NULL;
 tmpdir=NULL;

 colbase=1;
 colstatstr="2";

 linesize=240;
 preallocarg=NULL;

 i=scanarg(argc,argv,SCANARG_ALLOW_FLAGS,
	"--version:%NS-1f%q",&is_help,
        "--version-short|--short-version:%NS-2f%q",&is_help,
	"-C|--comment:%i",&is_comment,
	"-S|--additional-comment:%Dt",&additionalcomments,
	"-h|--help|--short-help|--help-short:%f%q",&is_help,
	"--long-help|--help-long:%SN2f%q",&is_help,
	"--mediawiki-help|--help-mediawiki|--wiki-help|--help-wiki:%SN3f%q",&is_help,
	"-b|--basename:%s",&basename,
	"-o|--output:%s",&outfile,
	"-x|--extension:%s",&extension,
	"-p|--prefix:%s",&prefix,
	"-a|--pre-allocate:%s",&preallocarg,
	"-m|--max-mem|--max-memory:%s",&maxmemstr,
	"-s|--stat:%s",&statstr,
	"-t|--tmpdir|--tempdir|--temporary-directory:%s",&tmpdir,
	"-r|--rejection:%Dt",&rejectionlist,
	"-l|--linesize|--line-size:%d",&linesize,
	"-c|--col-base:%d",&colbase,
	"-d|--col-stat:%s",&colstatstr,
	"--comment:%f",&is_comment,"(C):%f",&is_comment,
	"--verbose:%i",&is_verbose,"(V):%i",&is_verbose,
	"-:%Dl",&infiles,
	"-*|+*:%e",
	"*:%Dl",&infiles,
	NULL);

 if ( i )		
  {	fprint_error("invalid command line argument near '%s'",argv[i]);
	return(1);
  }
 else if ( is_help<0 )
  {	fprint_generic_version(stdout,argv[0],"grcollect",FITSH_GRCOLLECT_VERSION,is_help);
	return(0);
  }
 else if ( 1=ncolstat ) )
		 {	fprint_error("invalid rejection content (index=%d)",index);
			return(1);
		 }
		colstats[j].r.center=r.center|magtype;
		colstats[j].r.magnitude=r.magnitude;
		colstats[j].r.iterations=r.iterations;
	 }
  }
			

 if ( basename != NULL && (extension != NULL || prefix != NULL) )
  {	fprint_error("invalid combination of command line arguments");
	return(1);
  }
 else if ( extension != NULL || prefix != NULL )
  {	int	len;
	len=3;
	if ( extension != NULL )	len+=strlen(extension)+1;
	if ( prefix != NULL )		len+=strlen(prefix)+1;
	basename=malloc(len);
	if ( extension != NULL && prefix != NULL )
		sprintf(basename,"%s%%b.%s",prefix,extension);
	else if ( extension==NULL && prefix != NULL )
		sprintf(basename,"%s%%b",prefix);
	else if ( extension != NULL && prefix==NULL )
		sprintf(basename,"%%b.%s",extension);
  }

 if ( basename==NULL && outfile==NULL )
  {	fprint_error("neither basename nor output file name has been specified");
	return(1);
  }
 else if ( basename != NULL && outfile != NULL )
  {	fprint_error("both basename and output file name have been specified");
	return(1);
  }

 if ( infiles==NULL )	return(0);	/* no input files */
 for ( ninfile=0 ; infiles[ninfile] != NULL ; )	ninfile++;
 if ( ninfile<=0 )	return(0);	/* no input files */

 if ( linesize<0 )	linesize=240;
 linesize=(linesize+8+16)&(~0xf);
/* fprintf(stderr,"linesize=%d\n",linesize); */

 if ( basename != NULL )		/* do transposition */
  {	/* fprintf(stderr,"tmpdir=%s\n",tmpdir); */

	if ( preallocarg==NULL )
		preallocate=0;

	else
	 {	int	s1,s2;
		off_t	pagesize;

		i=sscanf(preallocarg,"%d,%d",&s1,&s2);
		if ( i<1 )
		 {	fprint_error("unexpected pre-allocation size definition '%s'",preallocarg);
			return(1);
		 }
		else if ( i<2 )
			preallocate=(off_t)s1;
		else
		 {	s1=(s1+15)&(~15);
			s2=(s2+15)&(~15);
			preallocate=((off_t)s1)*((off_t)s2);
		 }
#ifdef	HOST_WIN32
		pagesize=(off_t)4096;
#else
		pagesize=(off_t)getpagesize();
#endif
		preallocate=(preallocate+pagesize-1)&(~(pagesize-1));
	 }

	/*
	if ( tmpdir == NULL )
	*/

	do_transposition_normal(infiles,ninfile,
		colbase,basename,maxmem,preallocate,
		additionalcomments,argc,argv);

	/*
	else
		do_transposition_cached(infiles,ninfile,colbase,basename,maxmem,tmpdir,linesize);
	*/

	return(0);
  }

 if ( outfile != NULL )
  {	FILE	*fw;
	fw=fopenwrite(outfile);
	if ( fw==NULL )
	 {	fprint_error("unable to create output file '%s'",outfile);
		return(1);
	 }
	do_collective_statistics(infiles,ninfile,fw,colbase,
		colstats,ncolstat,statlist,maxmem,tmpdir);
	fclosewrite(fw);
	return(0);
  }

 return(0);
}

/*****************************************************************************/

fitsh-0.9.2/VERSION0000644000175000017500000000000611745470057012331 0ustar  apalapal0.9.2
fitsh-0.9.2/AUTHORS0000644000175000017500000000003412771512703012325 0ustar  apalapalAndras Pal 
fitsh-0.9.2/libastro/0000755000175000017500000000000012772016355013102 5ustar  apalapalfitsh-0.9.2/libastro/easpec.c0000644000175000017500000001062411236271021014474 0ustar  apalapal/*****************************************************************************/
/* easpec.c 								     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Calculates Earth-specific quantities (inclination of the rotation axis,   */
/* sideral time, geocentric position of an observer, ...)		     */
/* This part of the library is not standalone (depends on earth and cmath).  */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* (c) 2003, 2006; Pal, A. (apal@szofi.elte.hu).			     */ 
/*****************************************************************************/

#include 
#include 

#include 
#include 
#include 

/*****************************************************************************/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841968
#endif

/*****************************************************************************/

double get_earth_axis_angle(double jdate)
{
 double	jc;
 static double cjdate=0.0,ce=0.0;

 if ( cjdate==jdate )	return(ce);

 jc=(jdate-2451545.0)/36525.0;
 ce=23.439291+(-0.0130042+(-0.00000016+0.000000504*jc)*jc)*jc;
 cjdate=jdate;
 return(ce);
}

double get_sideral_time(double jdate)
{
 double	jc,jday;
 static double cjdate=0.0,csid=0.0;

 if ( cjdate==jdate )	return(csid);

 jday=(double)((long)(jdate-0.5))+0.5;
 jc=(jday-2415020.0)/36525.0;
 csid=0.276919398+(100.0021359+0.000001075*jc)*jc;

 csid+=1.002737908*(jdate-jday);
 if ( csid<0 )	csid+=(double)((long)(-csid))+10.0;
 csid=csid-(double)((long)csid);
 csid=csid*360.0;

 cjdate=jdate;

 return(csid);
}

void get_observer_coords(double jdate,double lon,double lat,double *x,double *y,double *z)
{
 double	wx,wy,n,d,lst;

 lst=get_sideral_time(jdate)+lon;

 wx=r_earth_equ*cosa(lat);
 wy=r_earth_pol*sina(lat);
 n=sqrt(wx*wx+wy*wy);
 d =r_earth_equ*wx/n;
 *z=r_earth_pol*wy/n;
 *x=d*cosa(lst);
 *y=d*sina(lst);
}

double get_heliocentric_julian_date(double jd,double ra,double dec)
{
 double rx,ry,rz;
 double nx,ny,nz;
 double	eps,dis,hjd;

 get_earth_coords(jd,&rx,&ry,&rz);
 eps=get_earth_axis_angle(jd);

 nx=cosa(dec)*cosa(ra);
 ny=cosa(dec)*sina(ra);
 nz=sina(dec);

 rotate(&ny,&nz,-eps);

/* jd0=get_julian_date(2000,1,1); */
/* rotate(&nx,&ny,(jd-jd0)/(365.25*25800.0)*360.0); */

 dis=nx*rx+ny*ry+nz*rz;

 hjd=jd + dis * 0.0057755178;

 return(hjd);
}

double get_heliocentric_julian_date_epoch(double jd,double ra,double dec,double y0)
{
 double rx,ry,rz;
 double nx,ny,nz;
 double	eps,dis,hjd,jd0;

 get_earth_coords(jd,&rx,&ry,&rz);
 eps=get_earth_axis_angle(jd);

 nx=cosa(dec)*cosa(ra);
 ny=cosa(dec)*sina(ra);
 nz=sina(dec);

 rotate(&ny,&nz,-eps);

 jd0=2451545.0+(y0-2000.0)*365.25;
 rotate(&nx,&ny,(jd-jd0)/(365.25*25800.0)*360.0);

 dis=nx*rx+ny*ry+nz*rz;

 hjd=jd + dis * 0.0057755178;

 return(hjd);
}

double get_barycentric_julian_date(double jd,double ra,double dec)
{
 double rx,ry,rz;
 double nx,ny,nz;
 double	bx,by,bz,tmass;
 double	jupx,jupy,jupz,
	satx,saty,satz,
	urax,uray,uraz,
	nepx,nepy,nepz;
 double	eps,dis,hjd;

 get_planet_coords(jd,5,&jupx,&jupy,&jupz);
 get_planet_coords(jd,6,&satx,&saty,&satz);
 get_planet_coords(jd,7,&urax,&uray,&uraz);
 get_planet_coords(jd,8,&nepx,&nepy,&nepz);
 tmass=1+m_jupiter+m_saturn+m_uranus+m_neptune;
 bx=(jupx*m_jupiter+satx*m_saturn+urax*m_uranus+nepx*m_neptune)/tmass;
 by=(jupy*m_jupiter+saty*m_saturn+uray*m_uranus+nepy*m_neptune)/tmass;
 bz=(jupz*m_jupiter+satz*m_saturn+uraz*m_uranus+nepz*m_neptune)/tmass;

 get_earth_coords(jd,&rx,&ry,&rz);

 rx-=bx;
 ry-=by;
 rz-=bz; 

 eps=get_earth_axis_angle(jd);

 nx=cosa(dec)*cosa(ra);
 ny=cosa(dec)*sina(ra);
 nz=sina(dec);

 rotate(&ny,&nz,-eps);

/* jd0=get_julian_date(2000,1,1); */
/* rotate(&nx,&ny,(jd-jd0)/(365.25*25800.0)*360.0); */

 dis=nx*rx+ny*ry+nz*rz;

 hjd=jd + dis * 0.0057755178;

 return(hjd);
}

int get_annular_parallax_correction(double jd,double ra,double dec,double dis,double *rra,double *rdec)
{
 double	x0,y0,z0,dx,dy,dz,eps;
 
 x0=dis*cosa(dec)*cosa(ra);
 y0=dis*cosa(dec)*sina(ra);
 z0=dis*sina(dec);
 
 get_earth_coords(jd,&dx,&dy,&dz);
 eps=get_earth_axis_angle(jd);
 rotate(&dy,&dz,+eps);
 x0+=dx*M_PI/(180.0*3600.0);
 y0+=dy*M_PI/(180.0*3600.0);
 z0+=dz*M_PI/(180.0*3600.0);

 *rra=getpcoords(x0,y0);
 dis=sqrt(x0*x0+y0*y0+z0*z0);
 *rdec=asina(z0/dis);
 
 return(0);
}

/*****************************************************************************/
                                  
fitsh-0.9.2/libastro/earth.c0000644000175000017500000000454011236271015014342 0ustar  apalapal/*****************************************************************************/
/* earth.c 								     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Calculates the heliocentric ecliptical Cartesian coordinates of Earth.    */
/* This part of the library is not standalone (depends on cmath.[ch]).	     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* (c) 2003, 2006; Pal, A. (apal@szofi.elte.hu).			     */
/*****************************************************************************/

#include 
#include 
#include 

#include 
#include 

/*****************************************************************************/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841968
#endif

/*****************************************************************************/

int get_earth_coords(double jdate,double *rx,double *ry,double *rz)
{
 double		jc1,jc2,jc3,x;
 double		l0,m0,e0,v0,th,em,o0;
 double		la,dis;
 static double	chx,chy,chz,cjdate;
 static int	is_valid_cache=0;

 if ( is_valid_cache && cjdate==jdate )
  {	*rx=chx;*ry=chy;*rz=chz;
	return(0);
  }

 jc1=(jdate-2415020.0)/36525.0;
 jc2=jc1*jc1;jc3=jc2*jc1;

 l0=279.69668+36000.76892*jc1+0.0003025*jc2;
 m0=358.47583+35999.04975*jc1-0.0001500*jc2-0.0000033*jc3;
 e0=0.01675101-0.0000418*jc1-0.000000126*jc2;

 em=solve_kepler_equ(m0*M_PI/180.0,e0);
 v0=sqrt((1.0+e0)/(1.0-e0))*tan(em/2.0);

 v0=2*atan(v0)*180.0/M_PI;
 th=l0+v0-m0+360.0;
 dis=1.0000002*(1-e0*cos(em));

 o0=(259.18-  1934.1420*jc1)*M_PI/180.0;
 th=th-0.00569-0.00479*sin(o0);
 
 x =(153.23+ 22518.7541*jc1)*M_PI/180.0,
 th+=0.00134*cos(x),dis+=0.00000543*sin(x);

 x =(216.57+ 45037.5082*jc1)*M_PI/180.0,
 th+=0.00154*cos(x),dis+=0.00001575*sin(x);

 x =(312.68+ 32964.3577*jc1)*M_PI/180.0,
 th+=0.00200*cos(x),dis+=0.00001627*sin(x);

 x =(350.74+445267.1142*jc1-0.00144*jc2)*M_PI/180.0;
 th+=0.00179*sin(x),dis+=0.00003076*cos(x);

 x=(231.19+   20.2000*jc1)*M_PI/180.0,th +=0.00178000*sin(x);
 x=(353.40+65928.7155*jc1)*M_PI/180.0,dis+=0.00000927*sin(x);

 la=(th-180.0)*M_PI/180.0;

 chx=*rx=dis*cos(la);
 chy=*ry=dis*sin(la);
 chz=*rz=0.0;

 is_valid_cache=1;
 cjdate=jdate;

 return(0);
}

/*****************************************************************************/
                                               
fitsh-0.9.2/libastro/planets.c0000644000175000017500000006313011236271132014705 0ustar  apalapal/*****************************************************************************/
/* ed_plan.c 								     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Calculates the heliocentric ecliptical Cartesian coordiants of planets.   */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Written by Kospal, A. (kospal@szofi.elte.hu)	and Pal, A. 		     */
/* (apal@szofi.elte.hu), maintained by Pal, A.				     */
/*****************************************************************************/

#include 
#include 

#include 

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841968
#endif

#define		EQNX1900
/* #define		EQNX2000 */

#ifdef		EQNX1900

/************************ EQUINOX 1900.0, T_0=1900.0 *************************/
/* Meeus page 95-97 */

static double	merc[]={				/* L,a,e,i,o,O */

    178.179078 , 0.3870986, 0.20561421 , 7.002881   ,28.753753   ,47.145944,
 149474.07078  , 0.0      , 0.00002046 , 0.0018608  , 0.3702806  , 1.1852083,
      0.0003011, 0.0      ,-0.000000030,-0.0000183  , 0.0001208  , 0.0001739,
      0.0      , 0.0      , 0.0        , 0.0        , 0.0        , 0.0
};

static double	venu[]={
   342.767053 , 0.7233316, 0.00682069 , 3.393631  ,54.384186   ,75.779647,
 58519.21191  , 0.0      ,-0.00004774 , 0.0010058 , 0.5081861  , 0.8998500,
     0.0003097, 0.0      , 0.000000091,-0.0000010 ,-0.0013864  , 0.0004100,
     0.0      , 0.0      , 0.0        , 0.0       , 0.0        , 0.0
};

static double	mars[]={
   293.737334 , 1.5236883, 0.09331290 , 1.850333   ,285.431761   , 48.786442,
 19141.69551  , 0.0      , 0.000092064,-0.0006750  ,  1.0697667  ,  0.7709917,
     0.0003107, 0.0      ,-0.000000077, 0.0000126  ,  0.0001313  , -0.0000014,
     0.0      , 0.0      , 0.0        , 0.0        ,  0.00000414 , -0.00000533
};

static double	jupi[]={
  238.049257  , 5.202561, 0.04833475  , 1.308736 , 273.277558  , 99.443414,
 3036.301986  , 0.0     , 0.000164180 ,-0.0056961,   0.5994317 ,  1.0105300,
    0.0003347 , 0.0     ,-0.0000004676, 0.0000039,   0.00070405,  0.00035222,
   -0.00000165, 0.0     ,-0.0000000017, 0.0      ,   0.00000508, -0.00000851
};

static double	satu[]={
  266.564377 ,9.554747, 0.05589232   , 2.492519  ,338.307800  ,112.790414,
 1223.509884 ,0.0     ,-0.00034550   ,-0.0039189 ,  1.0852207 ,  0.8731951,
    0.0003245,0.0     ,-0.000000728  ,-0.00001549,  0.00097854, -0.00015218,
   -0.0000058,0.0     , 0.00000000074, 0.00000004,  0.00000992, -0.00000531
};


#else
#ifdef EQNX2000

/************************ EQUINOX 2000.0, T_0=1900.0 *************************/
/* Meeus page 95-97 + 100-101 */

static double	merc[]={				/* L,a,e,i,o,O */

    178.179078 , 0.3870986, 0.20561421 , 7.010678   ,28.839814   ,48.456876,
 149474.07078  , 0.0      , 0.00002046 ,-0.0059556  , 0.2842765  ,-0.1254715,
      0.0003011, 0.0      ,-0.000000030, 0.00000069 , 0.00007445 ,-0.00008844,
      0.0      , 0.0      , 0.0        ,-0.000000035, 0.000000043,-0.000000068
};

static double	venu[]={
   342.767053 , 0.7233316, 0.00682069 , 3.395459  ,54.602827   ,76.957740,
 58519.21191  , 0.0      ,-0.00004774 ,-0.0007913 , 0.2892764  ,-0.2776656,
     0.0003097, 0.0      , 0.000000091,-0.0000325 ,-0.00114464 ,-0.0001401,
     0.0      , 0.0      , 0.0        , 0.00000018,-0.000000794, 0.000000769
};

static double	mars[]={
   293.737334 , 1.5236883, 0.09331290 , 1.857866   ,285.762379   , 49.852347,
 19141.69551  , 0.0      , 0.000092064,-0.0081565  ,  0.7387251  , -0.2941821,
     0.0003107, 0.0      ,-0.000000077,-0.00002304 ,  0.00046556 , -0.00064344,
     0.0      , 0.0      , 0.0        ,-0.000000044,  0.000006939, -0.000008159
};

static double	jupi[]={
  238.049257  , 5.202561, 0.04833475  , 1.305288   , 273.829584   ,100.287838,
 3036.301986  , 0.0     , 0.000164180 ,-0.0022374  ,   0.0478404  ,  0.1659357,
    0.0003347 , 0.0     ,-0.0000004676, 0.00002942 ,  -0.00021857 ,  0.00096672,
   -0.00000165, 0.0     ,-0.0000000017, 0.000000127,   0.000008999, -0.00001246
};

static double	satu[]={
  266.564377 ,9.554747, 0.05589232   , 2.486204   ,338.571353   ,113.923406,
 1223.509884 ,0.0     ,-0.00034550   , 0.0024449  ,  0.8220515  , -0.2599254,
    0.0003245,0.0     ,-0.000000728  ,-0.00005017 ,  0.00070747 , -0.00018997,
   -0.0000058,0.0     , 0.00000000074, 0.000000002,  0.000006177, -0.000001589
};


#else

#error	"Invalid equinox"

#endif
#endif

/************ EQUINOX 2000.0, Uranus, Neptune, Pluto, T_0=2000.0 *************/

static double	uran[]={			/* L, a, e, i, ~o (!), O */
  313.23218, 19.19126, 0.0471677 , 0.76986, 170.96424, 74.22988,
  428.48549, 0.00152, -0.00019155,-0.00058, 0.3646, -0.4670565,
 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0
};

static double	nept[]={
  304.88003 , 30.068963, 0.00858587, 1.76917    , 44.97135, 131.72169  ,
 218.4581139, -0.001252, 0.00000251, -0.00101111, -0.23456, -0.04201389,
 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0
};


static double	plut[]={
238.92881, 39.48168677, 0.24880766, 17.14175, 224.06676, 110.30347,
145.20775,0,0,0,0,0,
0,0,0,0,0,0,
0,0,0,0,0,0 
};


/* nept: */
/* 30.06896348, 0.00858587, 1.76917, 131.72169,  44.97135, 304.88003, */
/* -0.00125196,  0.0000251,   -3.64,   -151.25,   -844.43, 786449.21  */

/* plut: */
/* 39.48168677, 0.24880766,17.14175, 110.30347, 224.06676, 238.92881, */
/* -0.00076912, 0.00006465,   11.07,    -37.33,   -132.25, 522747.90  */


static double pol_jupi[]={
 0.331364, -0.010281,-0.0004692,
 0.003228, -0.064436, 0.002075,
-0.003083, -0.000275, 0.000489,
 0.002472,  0,        0,
 0.013619,  0,        0,
 0.018472,  0,        0,
 0.006717,  0,        0,
 0.002775,  0,        0,
 0.007275, -0.001253, 0,
 0.006417,  0,        0,
 0.002439,  0,        0,
-0.033839, -0.001125, 0,
-0.003767,  0,        0,
-0.035681, -0.001208, 0,
-0.004261,  0,        0,
 0.002178,  0,        0,
-0.006333,  0.001161, 0,
-0.006675,  0,        0,
-0.002664,  0,        0,
-0.002572,  0,        0,
-0.003567,  0,        0,
 0.002094,  0,        0,
 0.003342,  0,        0,  /* perturbations in the mean longitude (Meeus page 106) */

     3606,  130, -43,
     1289, -580,   0,
    -6764,    0,   0,
    -1110,    0,   0,
     -224,    0,   0,
     -204,    0,   0,
     1284,  116,   0,
      188,    0,   0,
     1460,  130,   0,
      224,    0,   0,
     -817,    0,   0,
     6074,    0,   0,
      992,    0,   0,
      508,    0,   0,
      230,    0,   0,
      108,    0,   0,
     -956,  -73,   0,
      448,    0,   0,
      137,    0,   0,
     -997,  108,   0,
      480,    0,   0,
      148,    0,   0,
     -956,   99,   0,
      490,    0,   0,
      158,    0,   0,
      179,    0,   0,
     1024,   75,   0,
     -437,    0,   0,
     -132,    0,   0,  /* perturbatin in the eccentricity (Meeus page 106-107) */

 0.007192, -0.003147, 0,
-0.020428, -0.000675, 0.000197,
 0.007269,  0.000672, 0,
-0.004344,  0,        0,
 0.034036,  0,        0,
 0.005614,  0,        0,
 0.002964,  0,        0, 
 0.037761,  0,        0, 
 0.006158,  0,        0,
-0.006603,  0,        0,
-0.005356,  0,        0,
 0.002722,  0,        0,
 0.004483,  0,        0,
-0.002642,  0,        0,
 0.004403,  0,        0,
-0.002536,  0,        0,
 0.005547,  0,        0,
-0.002689,  0,        0, /* perturbations in the perihelion (Meeus page 107) */

 -263, 0, 0,
  205, 0, 0,
  693, 0, 0,
  312, 0, 0,
  147, 0, 0,
  299, 0, 0, 
  181, 0, 0, 
  204, 0, 0, 
  111, 0, 0,
 -337, 0, 0,
 -111, 0, 0 /* perturbations is the semimajor axis (Meeus page 108) */
};

static double pol_satu[]={

 -0.814181, 0.018150	,-0.016714,
 -0.010497, 0.160906	,-0.004100,
  0.007581, 0		, 0,
 -0.007986, 0		, 0,
 -0.148811, 0		, 0,
 -0.040786, 0		, 0,
 -0.015208, 0		, 0,
 -0.006339, 0		, 0,
 -0.006244, 0		, 0,
  0.008931, 0.002728	, 0,
 -0.016500, 0		, 0,
 -0.005775, 0		, 0,
  0.081344, 0.003206	, 0,
  0.015019, 0		, 0,
  0.085581, 0.002494	, 0,
  0.025328,-0.003117	, 0,
  0.014394, 0		, 0,
  0.006319, 0		, 0,
  0.006369, 0		, 0,
  0.009156, 0		, 0,
  0.007525, 0		, 0,
 -0.005236, 0		, 0,
 -0.007736, 0		, 0,
 -0.007528, 0		, 0,  /* perturbations in the mean longitude (Meeus page 109) */

 -7927, 2548, 91,
 13381, 1226,-253,
   248, -121, 0,
  -305,  -91, 0, 
   412,    0, 0,
 12415,    0, 0,
   390, -617, 0,
   165, -204, 0,
 26599,    0, 0,
 -4687,    0, 0,
 -1870,    0, 0,
  -821,    0, 0,
  -377,    0, 0,
   497,    0, 0,
   163, -611, 0,
-12696,    0, 0,
 -4200,    0, 0,
 -1503,    0, 0,
  -619,    0, 0,
  -268,    0, 0,
  -282,-1306, 0,
   -86,  230, 0,
   461,    0, 0,
  -350,    0, 0,
  2211, -286, 0,
 -2208,    0, 0,
  -568,    0, 0,
  -346,    0, 0,
 -2780, -222, 0,
  2022,  263, 0,
   248,    0, 0,
   242,    0, 0,
   467,    0, 0,
  -490,    0, 0,
 -2842, -279, 0,
   128,  226, 0,
   224,    0, 0,
 -1594,  282, 0,
  2162, -207, 0,
   561,    0, 0,
   343,    0, 0,
   469,    0, 0,
  -242,    0, 0,
  -205,    0, 0,
   262,    0, 0, 
   208,    0, 0, 
  -271,    0, 0, 
  -382,    0, 0, 
  -376,    0, 0,  /* petrurbations in the eccentricity (Meeus page 109-110) */

  0.077108, 0.007186	, -0.001533,
  0.045803,-0.014766	, -0.000536,
 -0.007075, 0		, 0,
 -0.075825, 0		, 0,
 -0.024839, 0		, 0,
 -0.008631, 0		, 0,
 -0.072586, 0		, 0,
 -0.150383, 0		, 0,
  0.026897, 0		, 0,
  0.010053, 0		, 0,
 -0.013597,-0.001719	, 0,
 -0.007742, 0.001517	, 0,
  0.013586,-0.001375	, 0,
 -0.013667, 0.001239	, 0,
  0.011981, 0		, 0,
  0.014861, 0.001136	, 0,
 -0.013064,-0.001628	, 0,  /* perturbations in the perihelion (Meeus page 111) */

   572,   0, 0,
  2933,   0, 0,
 33629,   0, 0,
 -3081,   0, 0,
 -1423,   0, 0,
  -671,   0, 0,
  -320,   0, 0,
  1098,   0, 0,
 -2812,   0, 0,
   688,   0, 0,
  -393,   0, 0,
  -228,   0, 0,
  2138,   0, 0,
  -999,   0, 0,
  -642,   0, 0,
  -325,   0, 0,
  -890,   0, 0,
  2206,   0, 0,
 -1590,   0, 0,
  -647,   0, 0,
  -344,   0, 0,
  2885,   0, 0,
  2172, 102, 0,
   296,   0, 0,
  -267,   0, 0,
  -778,   0, 0,
   495,   0, 0,
   250,   0, 0,
  -856,   0, 0,
   441,   0, 0,
   296,   0, 0,
   211,   0, 0,
  -427,   0, 0,
   398,   0, 0,
   344,   0, 0,
  -427,   0, 0 /* perturbations in the semimajor axis (Meeus page 111) */
};


/* 1900 */
/* static double	uran[]={
 244.197470  ,19.21814, 0.0463444  ,0.772464 ,98.071581  ,73.477111,
 429.863546  , 0.0    ,-0.00002658 ,0.0006253, 0.9857650 , 0.4986678,
   0.0003160 , 0.0    , 0.000000077,0.0000395,-0.0010745 , 0.0013117,
  -0.00000060, 0.0    , 0.0        ,0.0      ,-0.00000061, 0.0
};

static double	nept[]={
  84.457994  ,30.10957, 0.00890704 , 1.779242 ,276.045975   ,130.681389,
 219.885914  , 0.0    , 0.000006330,-0.0095436,  0.3256394  ,  1.0989350,
   0.0003205 , 0.0    ,-0.000000002,-0.0000091,  0.00014095 ,  0.00024987,
  -0.00000060, 0.0    , 0.0        , 0.0      ,  0.000004113, -0.000004718
}; */

/* 2000 */
/* static double	uran[]={
 244.197470  ,19.21814, 0.0463444  , 0.774950   ,99.021587   ,73.923501,
 429.863546  , 0.0    ,-0.00002658 ,-0.0017660  , 0.0337219  , 0.0545828,
   0.0003160 , 0.0    , 0.000000077,-0.00000027 ,-0.00049812 , 0.00042674,
  -0.00000060, 0.0    , 0.0        , 0.000000123, 0.000013904,-0.000014536
};

static double	nept[]={
  84.457994  ,30.10957, 0.00890704 , 1.769715   ,276.335328   ,131.788486,
 219.885914  , 0.0    , 0.000006330,-0.0000144  ,  0.0368127  , -0.0084187,
   0.0003205 , 0.0    ,-0.000000002,-0.00000227 ,  0.00003849 ,  0.00004428,
  -0.00000060, 0.0    , 0.0        , 0.000000018,  0.000002226, -0.000002858
};
*/
                              


static	void sum_jupiter_perturbations(	double *ax,double *ex,double *el,
					double *mm,double *om,double jc1)
{
 double	nu,nu2,pe,ku,es,ve,zeta,a,b,ex1,ax1;

	nu  =jc1/5+0.1;
	nu2 =nu*nu;

	pe  =237.47555+3034.9061*jc1;
	ku  =265.91650+1222.1139*jc1;
	es  =243.51721+ 428.4677*jc1;

	ve  =5*ku-2*pe;
	zeta=  ku-  pe;

 a=
	(pol_jupi[ 0]+pol_jupi[ 1]*nu+pol_jupi[ 2]*nu2)*sina(ve)+
 	(pol_jupi[ 3]+pol_jupi[ 4]*nu+pol_jupi[ 5]*nu2)*cosa(ve)+
	(pol_jupi[ 6]+pol_jupi[ 7]*nu+pol_jupi[ 8]*nu2)*sina(2*ve)+
	(pol_jupi[ 9])*sina(2*pe-6*ku+3*es)+
	(pol_jupi[12])*sina(zeta)+
	(pol_jupi[15])*sina(2*zeta)+
	(pol_jupi[18])*sina(3*zeta);
	a+=
	(pol_jupi[21])*sina(4*zeta)+
	(pol_jupi[24]+pol_jupi[25]*nu)*sina(zeta)*sina(ku)+
	(pol_jupi[27])*sina(2*zeta)*sina(ku)+
	(pol_jupi[30])*sina(3*zeta)*sina(ku)+
	(pol_jupi[33]+pol_jupi[34]*nu)*cosa(zeta)*sina(ku)+
	(pol_jupi[36])*cosa(2*zeta)*sina(ku);
	a+=
	(pol_jupi[39]+pol_jupi[40]*nu)*sina(zeta)*cosa(ku)+
	(pol_jupi[42])*sina(2*zeta)*cosa(ku)+
	(pol_jupi[45])*cosa(ku)+
	(pol_jupi[48]+pol_jupi[49]*nu)*cosa(zeta)*cosa(ku)+
	(pol_jupi[51])*cosa(2*zeta)*cosa(ku)+
	(pol_jupi[54])*cosa(3*zeta)*cosa(ku);
	a+=
	(pol_jupi[57])*sina(zeta)*sina(2*ku)+
	(pol_jupi[60])*sina(2*zeta)*sina(2*ku)+
	(pol_jupi[63])*cosa(zeta)*cosa(2*ku)+
	(pol_jupi[66])*cosa(2*zeta)*cosa(2*ku);

	ex1=
	(pol_jupi[ 69]+pol_jupi[ 70]*nu+pol_jupi[ 71]*nu2)*sina(ve)+
	(pol_jupi[ 72]+pol_jupi[ 73]*nu)*cosa(ve)+
	(pol_jupi[ 75])*sina(zeta)*sina(ku)+
	(pol_jupi[ 78])*sina(2*zeta)*sina(ku)+
	(pol_jupi[ 81])*sina(3*zeta)*sina(ku)+
	(pol_jupi[ 84])*sina(ku)+
	(pol_jupi[ 87]+pol_jupi[ 88]*nu)*cosa(zeta)*sina(ku)+
	(pol_jupi[ 90])*cosa(2*zeta)*sina(ku);
	ex1+=
	(pol_jupi[ 93]+pol_jupi[ 94]*nu)*sina(zeta)*cosa(ku)+
	(pol_jupi[ 96])*sina(2*zeta)*cosa(ku)+
	(pol_jupi[ 99])*cosa(ku)+
	(pol_jupi[102])*cosa(zeta)*cosa(ku)+
	(pol_jupi[105])*cosa(2*zeta)*cosa(ku)+
	(pol_jupi[108])*cosa(3*zeta)*cosa(ku);
	ex1+=
	(pol_jupi[111])*cosa(4*zeta)*cosa(ku)+
	(pol_jupi[114])*cosa(5*zeta)*cosa(ku)+
	(pol_jupi[117]+pol_jupi[118]*nu)*sina(zeta)*sina(2*ku)+
	(pol_jupi[120])*sina(2*zeta)*sina(2*ku)+
	(pol_jupi[123])*sina(3*zeta)*sina(2*ku)+
	(pol_jupi[126]+pol_jupi[127]*nu)*cosa(zeta)*sina(2*ku)+
	(pol_jupi[129])*cosa(2*zeta)*sina(2*ku)+
	(pol_jupi[132])*cosa(3*zeta)*sina(2*ku);
	ex1+=
	(pol_jupi[135]+pol_jupi[136]*nu)*sina(zeta)*cosa(2*ku)+
	(pol_jupi[138])*sina(2*zeta)*cosa(2*ku)+
	(pol_jupi[141])*sina(3*zeta)*cosa(2*ku)+
	(pol_jupi[144])*cosa(2*ku)+
	(pol_jupi[147]+pol_jupi[148]*nu)*cosa(zeta)*cosa(2*ku)+
	(pol_jupi[150])*cosa(2*zeta)*cosa(2*ku)+
	(pol_jupi[153])*cosa(3*zeta)*cosa(2*ku);
	ex1*=1e-7;

	b=
	(pol_jupi[156]+pol_jupi[157]*nu)*sina(ve)+
	(pol_jupi[159]+pol_jupi[160]*nu+pol_jupi[161]*nu2)*cosa(ve)+
	(pol_jupi[162]+pol_jupi[163]*nu)*sina(zeta)*sina(ku)+
	(pol_jupi[165])*sina(ku)+
	(pol_jupi[168])*cosa(zeta)*sina(ku)+
	(pol_jupi[171])*cosa(2*zeta)*sina(ku)+
	(pol_jupi[174])*cosa(3*zeta)*sina(ku)+
	(pol_jupi[177])*sina(zeta)*cosa(ku)+
	(pol_jupi[180])*sina(2*zeta)*cosa(ku);
	b+=
	(pol_jupi[183])*cosa(zeta)*cosa(ku)+
	(pol_jupi[186])*sina(zeta)*sina(2*ku)+
	(pol_jupi[189])*sina(2*zeta)*sina(2*ku)+
	(pol_jupi[192])*cosa(zeta)*sina(2*ku)+
	(pol_jupi[195])*cosa(2*zeta)*sina(2*ku)+
	(pol_jupi[198])*sina(zeta)*cosa(2*ku)+
	(pol_jupi[201])*sina(2*zeta)*cosa(2*ku)+
	(pol_jupi[204])*cosa(zeta)*cosa(2*ku)+
	(pol_jupi[207])*cosa(2*zeta)*cosa(2*ku);
	
	ax1=(
	(pol_jupi[210])*cosa(ve)+
	(pol_jupi[213])*cosa(zeta)+
	(pol_jupi[216])*cosa(2*zeta)+
	(pol_jupi[219])*cosa(3*zeta)+
	(pol_jupi[222])*cosa(4*zeta)+
	(pol_jupi[225])*sina(zeta)*sina(ku)+
	(pol_jupi[228])*cosa(2*zeta)*sina(ku)+
	(pol_jupi[231])*sina(2*zeta)*cosa(ku)+
	(pol_jupi[234])*sina(3*zeta)*cosa(ku)+
	(pol_jupi[237])*cosa(zeta)*cosa(ku)+
	(pol_jupi[240])*cosa(2*zeta)*cosa(ku)
	)*1e-6;

 (*ax)+=ax1;
 (*el)+=a;
 (*om)+=b;
 (*mm)+=a-b/(*ex);
 (*ex)+=ex1;
}
static	void sum_saturn_perturbations(	double *ax,double *ex,double *el,
					double *mm,double *om,double jc1)
{
 double	nu,nu2,pe,ku,es,ve,zeta,psi,a,b,ax1,ex1;

	nu  =jc1/5+0.1;
	nu2 =nu*nu;

	pe  =237.47555+3034.9061*jc1;
	ku  =265.91650+1222.1139*jc1;
	es  =243.51721+ 428.4677*jc1;

	ve  =5*ku-2*pe;
	zeta=  ku-  pe;
	psi =  es-  ku;

	a=
	(pol_satu[ 0]+pol_satu[ 1]*nu+pol_satu[ 2]*nu2)*sina(ve)+
	(pol_satu[ 3]+pol_satu[ 4]*nu+pol_satu[ 5]*nu2)*cosa(ve)+
	(pol_satu[ 6])*sina(2*ve)+
	(pol_satu[ 9])*sina(2*pe-6*ku+3*es)+
	(pol_satu[12])*sina(zeta)+
	(pol_satu[15])*sina(2*zeta)+
	(pol_satu[18])*sina(3*zeta)+
	(pol_satu[21])*sina(4*zeta)+
	(pol_satu[24])*sina(ku)+
	(pol_satu[27]+pol_satu[28]*nu)*sina(zeta)*sina(ku)+
	(pol_satu[30])*sina(2*zeta)*sina(ku)+
	(pol_satu[33])*sina(3*zeta)*sina(ku)+
	(pol_satu[36]+pol_satu[37]*nu)*cosa(zeta)*sina(ku);
	a+=
	(pol_satu[39])*cosa(2*zeta)*sina(ku)+
	(pol_satu[42]+pol_satu[43]*nu)*sina(zeta)*cosa(ku)+
	(pol_satu[45]+pol_satu[46]*nu)*cosa(zeta)*cosa(ku)+
	(pol_satu[48])*cosa(2*zeta)*cosa(ku)+
	(pol_satu[51])*cosa(3*zeta)*cosa(ku)+
	(pol_satu[54])*sina(zeta)*sina(2*ku)+
	(pol_satu[57])*sina(2*zeta)*sina(2*ku)+
	(pol_satu[60])*sina(3*psi)*sina(2*ku)+
	(pol_satu[63])*cosa(zeta)*cosa(2*ku)+
	(pol_satu[66])*cosa(2*zeta)*cosa(2*ku)+
       	(pol_satu[69])*cosa(3*psi)*cosa(2*ku);
	
	ex1=
	(pol_satu[ 72]+pol_satu[ 73]*nu+pol_satu[ 74]*nu2)*sina(ve)+
	(pol_satu[ 75]+pol_satu[ 76]*nu+pol_satu[ 77]*nu2)*cosa(ve)+
	(pol_satu[ 78]+pol_satu[ 79]*nu)*sina(2*ve)+
	(pol_satu[ 81]+pol_satu[ 82]*nu)*cosa(2*ve)+
	(pol_satu[ 84])*sina(2*zeta)+
	(pol_satu[ 87])*sina(ku)+
	(pol_satu[ 90]+pol_satu[ 91]*nu)*sina(zeta)*sina(ku)+
	(pol_satu[ 93]+pol_satu[ 94]*nu)*sina(2*zeta)*sina(ku)+
	(pol_satu[ 96])*cosa(zeta)*sina(ku);
	ex1+=
	(pol_satu[ 99])*cosa(2*zeta)*sina(ku)+
	(pol_satu[102])*cosa(3*zeta)*sina(ku)+
	(pol_satu[105])*cosa(4*zeta)*sina(ku)+
	(pol_satu[108])*cosa(5*zeta)*sina(ku)+
	(pol_satu[111])*cosa(2*psi)*sina(ku)+
	(pol_satu[114]+pol_satu[115]*nu)*cosa(ku);
	ex1+=
	(pol_satu[117])*sina(zeta)*cosa(ku)+
	(pol_satu[120])*sina(2*zeta)*cosa(ku)+
	(pol_satu[123])*sina(3*zeta)*cosa(ku)+
	(pol_satu[126])*sina(4*zeta)*cosa(ku)+
	(pol_satu[129])*sina(5*zeta)*cosa(ku)+
	(pol_satu[132]+pol_satu[133]*nu)*cosa(zeta)*cosa(ku)+
	(pol_satu[135]+pol_satu[136]*nu)*cosa(2*zeta)*cosa(ku)+
	(pol_satu[138])*sina(2*psi)*cosa(ku)+
	(pol_satu[141])*sina(2*ku);
	ex1+=
	(pol_satu[144]+pol_satu[145]*nu)*sina(zeta)*sina(2*ku)+
	(pol_satu[147])*sina(2*zeta)*sina(2*ku)+
	(pol_satu[150])*sina(3*zeta)*sina(2*ku)+
	(pol_satu[153])*sina(4*zeta)*sina(2*ku)+
	(pol_satu[156]+pol_satu[157]*nu)*cosa(zeta)*sina(2*ku)+
	(pol_satu[159]+pol_satu[160]*nu)*cosa(2*zeta)*sina(2*ku)+
	(pol_satu[162])*cosa(3*zeta)*sina(2*ku);
	ex1+=
	(pol_satu[165])*sina(3*psi)*sina(2*ku)+
	(pol_satu[168])*cosa(3*psi)*sina(2*ku)+
	(pol_satu[171])*cosa(2*ku)+
	(pol_satu[174]+pol_satu[175]*nu)*sina(zeta)*cosa(2*ku)+
	(pol_satu[177]+pol_satu[178]*nu)*sina(2*zeta)*cosa(2*ku)+
	(pol_satu[180])*sina(3*zeta)*cosa(2*ku);
	ex1+=
	(pol_satu[183]+pol_satu[184]*nu)*cosa(zeta)*cosa(2*ku)+
	(pol_satu[186]+pol_satu[187]*nu)*cosa(2*zeta)*cosa(2*ku)+
	(pol_satu[189])*cosa(3*zeta)*cosa(2*ku)+
	(pol_satu[192])*cosa(4*zeta)*cosa(2*ku)+
	(pol_satu[195])*sina(3*psi)*cosa(2*ku)+
	(pol_satu[198])*cosa(3*psi)*cosa(2*ku);
	ex1+=
	(pol_satu[201])*sina(zeta)*sina(3*ku)+
	(pol_satu[204])*sina(3*zeta)*sina(3*ku)+
	(pol_satu[207])*cosa(zeta)*cosa(3*ku)+
	(pol_satu[210])*cosa(3*zeta)*cosa(3*ku)+
	(pol_satu[213])*cosa(3*zeta)*sina(4*ku)+
	(pol_satu[216])*sina(3*zeta)*cosa(4*ku);
	ex1*=1e-7;

	b=
	(pol_satu[219]+pol_satu[220]*nu+pol_satu[221]*nu2)*sina(ve)+
	(pol_satu[222]+pol_satu[223]*nu+pol_satu[224]*nu2)*cosa(ve)+
	(pol_satu[225])*sina(zeta)+
	(pol_satu[228])*sina(zeta)*sina(ku)+
	(pol_satu[231])*sina(2*zeta)*sina(ku)+
	(pol_satu[234])*sina(3*zeta)*sina(ku);
	b+=
	(pol_satu[237])*cosa(ku)+
	(pol_satu[240])*cosa(zeta)*cosa(ku)+
	(pol_satu[243])*cosa(2*zeta)*cosa(ku)+
	(pol_satu[246])*cosa(3*zeta)*cosa(ku);
	b+=
	(pol_satu[249]+pol_satu[250]*nu)*sina(zeta)*sina(2*ku)+
	(pol_satu[252]+pol_satu[253]*nu)*cosa(zeta)*sina(2*ku)+
	(pol_satu[255]+pol_satu[256]*nu)*cosa(2*zeta)*sina(2*ku)+
	(pol_satu[258]+pol_satu[259]*nu)*sina(zeta)*cosa(2*ku)+
	(pol_satu[261])*sina(2*zeta)*cosa(2*ku)+
	(pol_satu[264]+pol_satu[265]*nu)*cosa(zeta)*cosa(2*ku)+
	(pol_satu[267]+pol_satu[268]*nu)*cosa(2*zeta)*cosa(2*ku);

	ax1=
	(pol_satu[270])*sina(ve)+
	(pol_satu[273])*cosa(ve)+
	(pol_satu[276])*cosa(zeta)+
	(pol_satu[279])*cosa(2*zeta)+
	(pol_satu[282])*cosa(3*zeta)+
	(pol_satu[285])*cosa(4*zeta)+
	(pol_satu[288])*cosa(5*zeta)+
	(pol_satu[291])*sina(ku)+
	(pol_satu[294])*sin(zeta)*sina(ku)+
	(pol_satu[297])*sina(2*zeta)*sina(ku)+
	(pol_satu[300])*sina(3*zeta)*sina(ku)+
	(pol_satu[303])*sina(4*zeta)*sina(ku);
	ax1+=
	(pol_satu[306])*cosa(zeta)*sina(ku)+
	(pol_satu[309])*cosa(2*zeta)*sina(ku)+
	(pol_satu[312])*cosa(3*zeta)*sina(ku)+
	(pol_satu[315])*cosa(4*zeta)*sina(ku)+
	(pol_satu[318])*cosa(ku)+
	(pol_satu[321])*sina(zeta)*cosa(ku)+
	(pol_satu[324])*sina(2*zeta)*cosa(ku);
	ax1+=
	(pol_satu[327])*sina(3*zeta)*cosa(ku)+
	(pol_satu[330])*sina(4*zeta)*cosa(ku)+
	(pol_satu[333])*cosa(zeta)*cosa(ku)+
	(pol_satu[336]+pol_satu[337]*nu)*cosa(2*zeta)*cosa(ku)+
	(pol_satu[339])*cosa(3*zeta)*cosa(ku)+
	(pol_satu[342])*sina(2*zeta)*sina(2*ku);
	ax1+=
	(pol_satu[345])*cosa(zeta)*sina(2*ku)+
	(pol_satu[348])*cosa(2*zeta)*sina(2*ku)+
	(pol_satu[351])*cosa(3*zeta)*sina(2*ku)+
	(pol_satu[354])*sina(zeta)*cosa(2*ku)+
	(pol_satu[357])*sina(2*zeta)*cosa(2*ku)+
	(pol_satu[360])*cosa(2*zeta)*cosa(2*ku);
	ax1+=
	(pol_satu[363])*cosa(3*zeta)*cosa(2*ku)+
	(pol_satu[366])*sina(zeta)*sina(3*ku)+
	(pol_satu[369])*cosa(3*zeta)*sina(3*ku)+
	(pol_satu[372])*cosa(zeta)*cosa(3*ku)+
	(pol_satu[375])*cosa(3*zeta)*cosa(3*ku);
	ax1*=1e-6;

 *ax+=ax1;
 *el+=a;
 *om+=b;
 *mm+=a-b/(*ex);
 *ex+=ex1;
}
int get_planet_coords(double jdate, int n, double *rx, double *ry, double *rz)
{
 double	jc1,jc2,jc3,jckk,x,y,z;
 double	el,ax,ex,in,om,oo;
 double	m0,m1,m2,m4,m5,m6,mm,vv;
 double	e,er,la,be;
 double	*pd;

 jc1 =(jdate-2415020.0)/36525.0;	  /* JCent, 1900.01.01 12:00 UT */
 jc2 =jc1*jc1;
 jc3 =jc2*jc1;
 jckk=(jdate-2451545.0)/36525.0;	  /* JCent, 2000.01.01 12:00 UT */

 switch(n)
  {	case 1: pd=(double*)merc;break;
	case 2: pd=(double*)venu;break;
	case 4: pd=(double*)mars;break;
	case 5: pd=(double*)jupi;break;
	case 6: pd=(double*)satu;break;
	case 7: pd=(double*)uran;break;
	case 8: pd=(double*)nept;break;
	case 9: pd=(double*)plut;break;
	default: pd=NULL;break;
  };

 if ( pd==NULL )	return(-1);

 if ( n<=6 )
  {	el=pd[ 0]+pd[ 6]*jc1+pd[12]*jc2+pd[18]*jc3;  /* L, mean longitude */
	ax=pd[ 1]+pd[ 7]*jc1+pd[13]*jc2+pd[19]*jc3;  /* a, semimajor axis */
	ex=pd[ 2]+pd[ 8]*jc1+pd[14]*jc2+pd[20]*jc3;  /* e, eccentricity */
	in=pd[ 3]+pd[ 9]*jc1+pd[15]*jc2+pd[21]*jc3;  /* i, inclination */
	om=pd[ 4]+pd[10]*jc1+pd[16]*jc2+pd[22]*jc3;  /* \omega, argument of perihelion */
	oo=pd[ 5]+pd[11]*jc1+pd[17]*jc2+pd[23]*jc3;  /* \Omega, longitude of ascending node */
  }
 else
  {	el=pd[ 0]+pd[ 6]*jckk;  /* L, mean longitude */
	ax=pd[ 1]+pd[ 7]*jckk;  /* a, semimajor axis */
	ex=pd[ 2]+pd[ 8]*jckk;  /* e, eccentricity */
	in=pd[ 3]+pd[ 9]*jckk;  /* i, inclination */
	om=pd[ 4]+pd[10]*jckk;  /* \varpi, longitude of perihelion */
	oo=pd[ 5]+pd[11]*jckk;  /* \Omega, longitude of ascending node */
	om=om-oo;
  }
    
/* Sun's mean anomaly: */
    
 m0=358.47583+ 35999.04975*jc1-0.000150*jc2-0.0000033*jc3;
    
/* Planets' mean anomaly: */
    
 m1=102.27938+149472.51529*jc1+0.000007*jc2;	/* merc */
 m2=212.60322+ 58517.80387*jc1+0.001286*jc2;	/* venu */
 m4=319.51913+ 19139.85475*jc1+0.000181*jc2;	/* mars */
 m5=225.32833+  3034.69202*jc1-0.000722*jc2;	/* jupi */
 m6=175.46622+  1221.55147*jc1-0.000502*jc2;	/* satu */
    
/* Periodic perturbations in the elements of the planet's orbit: */
    
 switch(n)
  {  case 1:
	mm=m1;
	break;
     case 2: 
	mm=m2;
	el+=	+0.00077*sina(237.24+150.27*jc1);
	break;
     case 4: 
	mm=m4;
	el+=	-0.01133*sina(3*m5-8*m4+4*m0)
		-0.00933*cosa(3*m5-8*m4+4*m0);
	break;
     case 5:
	mm=m5;

	sum_jupiter_perturbations(&ax,&ex,&el,&mm,&om,jc1);

	break;

     case 6: 
	mm=m6;

	sum_saturn_perturbations(&ax,&ex,&el,&mm,&om,jc1);


	break;
     case 7: case 8: case 9:
	mm=el-om-oo;	/* Default mean anomaly: M=L-\Omega-\omega=L-\varpi */
	break;
    };

 e =solve_kepler_equ(mm*M_PI/180.0,ex);
 er=ax*(1-ex*cos(e));
 vv=getpcoords(cos(e)-ex, sqrt(1-ex*ex)*sin(e));

 la=el+vv-mm-oo;

 x=er*cosa(la);
 y=er*sina(la);
 z=0;
 rotate(&y,&z,in);
 rotate(&x,&y,oo);
 be=asina(z/er);
 la=getpcoords(x,y);
 
 switch(n)
  {  case 1: 
	la+=	+0.00204*cosa(5*m2-2*m1+ 12.220)
		+0.00103*cosa(2*m2-  m1-160.692)
		+0.00091*cosa(2*m5-  m1- 37.003)
		+0.00078*cosa(5*m2-3*m1+ 10.137);

	er+=	+0.000007525*cosa(2*m5-  m1+ 53.013)
		+0.000006802*cosa(5*m2-3*m1-259.918)
		+0.000005457*cosa(2*m2-2*m1- 71.188)
		+0.000003569*cosa(5*m2-  m1- 77.75);
		
	break;
     case 2:
	la+=	+0.00313*cosa(2*m0-2*m2-148.225)
		+0.00198*cosa(3*m0-3*m2+  2.565)
		+0.00136*cosa(  m0-  m2-119.107)
		+0.00096*cosa(3*m0-2*m2-135.912)
		+0.00082*cosa(  m5-  m2-208.087);

	er+=	+0.000022501*cosa(2*m0-2*m2- 58.208)
		+0.000019045*cosa(3*m0-3*m2+ 92.577)
		+0.000006887*cosa(  m5-  m2-118.090)
		+0.000005172*cosa(  m0-  m2- 29.110)
		+0.000003620*cosa(5*m0-4*m2-104.208)
		+0.000003283*cosa(4*m0-4*m2+ 63.513)
		+0.000003074*cosa(2*m5-2*m2- 55.167);

	break;
     case 4:
	la+=	+0.00705*cosa(  m5-  m4- 48.958)
		+0.00607*cosa(2*m5-  m4-188.380)
		+0.00445*cosa(2*m5-2*m4-191.897)
		+0.00388*cosa(  m0-2*m4+ 20.495)
		+0.00238*cosa(  m0-  m4+ 35.097)
		+0.00204*cosa(2*m0-3*m4+158.638)
		+0.00177*cosa(3*m4-  m2- 57.602)
		+0.00136*cosa(2*m0-4*m4+154.093)
		+0.00104*cosa(  m5     + 17.618);

	er+=	+0.000053227*cosa(  m5-  m4+ 41.1306)
		+0.000050989*cosa(2*m5-2*m4-101.9847)
		+0.000038278*cosa(2*m5-  m4- 98.3292)
		+0.000015996*cosa(  m0-  m4- 55.5550)
		+0.000014764*cosa(2*m0-3*m4+ 68.6220)
		+0.000008966*cosa(  m5-2*m4+ 43.6150)
		+0.000007914*cosa(3*m5-2*m4-139.7370)
		+0.000007004*cosa(2*m5-3*m4-102.8880)
		+0.000006620*cosa(  m0-2*m4+113.2020)
		+0.000004930*cosa(3*m5-3*m4- 76.2430)
		+0.000004693*cosa(3*m0-5*m4+190.6030)
		+0.000004571*cosa(2*m0-4*m4+244.7020)
		+0.000004409*cosa(3*m5-  m4-115.8280);

	break;
     case 6:
	x=237.47555+3034.9061*jc1;	/* PE */
	y=265.91650+1222.1139*jc1;	/* KU */
	x=y-x;				/* ZETA = KU-PE */

	be+=	+0.000747*cosa(  x)*sina(  y)
		+0.001069*cosa(  x)*cosa(  y)
		+0.002108*sina(2*x)*sina(2*y)
		+0.001261*cosa(2*x)*sina(2*y)
		+0.001236*sina(2*x)*cosa(2*y)
		-0.002075*cosa(2*x)*cosa(2*y);

	break;

 };

 *rx=er*cosa(be)*cosa(la);
 *ry=er*cosa(be)*sina(la);
 *rz=er*sina(be);

 return(0);
}

/*****************************************************************************/
                                     
fitsh-0.9.2/libastro/cmath.c0000644000175000017500000000665411236271001014336 0ustar  apalapal/*****************************************************************************/
/* cmath.c 								     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Common basic functions used by other modules.			     */
/* This part of the library (cmath.[ch]) is standalone.		             */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* (c) 2003-2006, Pal A. (apal@szofi.elte.hu).				     */
/*****************************************************************************/

#include 
#include 

#include 

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841968
#endif

/*****************************************************************************/

double sina(double x)	{	return(sin(x*M_PI/180.0));	}
double cosa(double x) 	{	return(cos(x*M_PI/180.0));	}
double asina(double x)	{	return(asin(x)*180.0/M_PI); 	}
double acosa(double x)	{	return(acos(x)*180.0/M_PI); 	}

/*****************************************************************************/

void rotate(double *x,double *y,double phi)
{
 double wx,wy;
 phi=phi*M_PI/180.0;
 wx=(*x)*cos(phi)-(*y)*sin(phi);
 wy=(*x)*sin(phi)+(*y)*cos(phi);
 *x=wx,*y=wy;
}
double getpcoords(double x,double y)
{
 if ( x==0 && y==0 )	return(0.0);
 x=atan2(y,x)*180.0/M_PI;
 if ( x<0.0 )	x+=360.0;
 return(x);
}
void get3dpcoords(double x,double y,double z,double *longi,double *latit)
{
 double	r;

 r=sqrt(x*x+y*y+z*z);
 if ( r==0.0 )	*latit=*longi=0;
 else 		*latit=asina(z/r),*longi=getpcoords(x,y);
}
double	get_angular_distance(double lon1,double lat1,double lon2,double lat2)
{
 double d,r;
 d=sina(lat1)*sina(lat2)+cosa(lat1)*cosa(lat2)*cosa(lon1-lon2);
 if ( d>1.0 )		r=0.0;
 else if ( d<-1.0 )	r=180.0;
 else			r=acosa(d);
 return(r);
}

/*****************************************************************************/

double	hypot3d(double x,double y,double z)
{
 return( sqrt(x*x+y*y+z*z) );
}

/*
double solve_kepler_equ(double m,double ex)
{
 double	e,e0;
 int	n;

 e=m+ex*sin(m)/(1-sin(m+ex)+sin(m));

 for ( n=15,e0=0.0 ; e != e0 && n>0 ; n-- )
  {	e0=e;
	e=e+(m+ex*sin(e)-e)/(1-ex*cos(e));
  };
 return(e);
}
*/

double solve_kepler_equ(double m,double e)
{
 double s,d,d0;
 int    n;

 s=sin(m);

 if ( s==0.0 )
        return(m);

 else if ( e>=0.8 && s*s<0.1 && cos(m)>0.0 )
  {     if ( s>0 )      d=+pow(+6*s,1.0/3.0);
        else            d=-pow(-6*s,1.0/3.0);
  }
 else
  {     d=e*s/(1-sin(m+e)+s);
	if ( d<-e )	d=-e;
	else if ( d>e )	d=+e;
  }

 for ( n=15,d0=0.0 ; d != d0 && n>0 ; n-- )
  {     d0=d;
        d=d-(d-e*sin(m+d))/(1-e*cos(m+d));
  };

 return(m+d);
}


/*****************************************************************************/

void matrix_rotation(matrix m,int ax,double fi)
{
 int	i,j,vi,vj;
 double	cfi,sfi;

 cfi=cosa(fi),sfi=sina(fi);
 ax=ax%3;
 
 for ( i=0 ; i<3 ; i++ )
  {	for ( j=0 ; j<3 ; j++ )
	 {	vi=(i-ax+3)%3,vj=(j-ax+3)%3;
		if ( vi==0 && vj==0 )	m[i][j]=1.0;
		else if ( vi==0 || vj==0 )	m[i][j]=0.0;
		else if ( vi==vj )	m[i][j]=cfi;
		else if ( vi==1 )	m[i][j]=-sfi;
		else			m[i][j]=+sfi;
	 }
  }
}

void matrix_mul(matrix r,matrix m1,matrix m2)	/* r = m1 * m2 ... */
{
 int	i,j;
 matrix	w;

 for ( i=0 ; i<3 ; i++ )
  {	for ( j=0 ; j<3 ; j++ )
		w[i][j]=m1[i][0]*m2[0][j]+m1[i][1]*m2[1][j]+m1[i][2]*m2[2][j];
  } 
 for ( i=0 ; i<3 ; i++ )
  {	for ( j=0 ; j<3 ; j++ )
		r[i][j]=w[i][j];
  }
}

/*****************************************************************************/
    
fitsh-0.9.2/libastro/Makefile.in0000644000175000017500000000227311657563455015164 0ustar  apalapalSHELL = /bin/sh

CC=@CC@
AR=@AR@
LD=@LD@
RANLIB=@RANLIB@

INC=../include

CFLAGS=@CFLAGS@ -I$(INC)

all: libastro.a

.PHONY: all clean

ASTRO_MODULES= \
	astro.o \
	cmath.o \
	dtc.o \
	earth.o \
	easpec.o \
	planets.o \
	output.o 

###############################################################################

libastro.a: $(ASTRO_MODULES)
	$(AR) src libastro.a $(ASTRO_MODULES)
	$(RANLIB) libastro.a

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 

astro.o: astro.c $(INC)/astro/astro.h
	$(CC) $(CFLAGS) -c astro.c

cmath.o: cmath.c $(INC)/astro/cmath.h
	$(CC) $(CFLAGS) -c cmath.c

dtc.o: dtc.c $(INC)/astro/dtc.h 
	$(CC) $(CFLAGS) -c dtc.c

earth.o: earth.c $(INC)/astro/earth.h $(INC)/astro/astro.h
	$(CC) $(CFLAGS) -c earth.c

easpec.o: easpec.c $(INC)/astro/easpec.h $(INC)/astro/astro.h
	$(CC) $(CFLAGS) -c easpec.c

planets.o: planets.c $(INC)/astro/planets.h $(INC)/astro/astro.h
	$(CC) $(CFLAGS) -c planets.c

output.o: output.c $(INC)/astro/output.h
	$(CC) $(CFLAGS) -c output.c

###############################################################################

clean:
	rm -f *.o *.a

###############################################################################
fitsh-0.9.2/libastro/dtc.c0000644000175000017500000000341011236271006014004 0ustar  apalapal/*****************************************************************************/
/* dtc.c 								     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Calculations between different types of date formats			     */
/* This part of the library (dtc.[ch]) is standalone!			     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* (c) 2003, 2006; Pal, A. (apal@szofi.elte.hu).			     */
/*****************************************************************************/

#include 
#include 

#include 

double read_julian_date(void)
{
 time_t	ctime;
 double	jd;

/* tzset(); */
 time(&ctime);

 jd=((double)ctime)/86400.0 + 2440587.5 ;

 return(jd);
}

double get_julian_date(int ye,int mo,int da)
{
 int	lya;
 double jd;

 if ( mo<=2 )	ye--,mo+=12;

 if ( ye>1582 || ( ye==1582 && mo>10 ) || ( ye==1582 && mo==10 && da>14 ) )
	lya=(2)-(ye/100)+(ye/400);
 else
	lya=0;

 jd=	(double)lya+
	1720994.5+
	(double)(((long)ye*1461L)/4L)+
	(double)((153*(mo+1))/5)+
	(double)da;

 return(jd);
}

void get_calendar_date(double jd,int *ye,int *mo,double *da)
{
 long	w,a,b,c,d,e,z;
 
 jd+=0.5;
 z=(long)jd;

 if ( z>=2299161L )
	w=(4L*z-7468865L)/146097L,a=1L+z+w-(w/4L);
 else	
	a=z;

 b=a+1524L;
 c=(20L*b-2442L)/7305L;
 d=(1461L*c)/4L;
 e=((b-d)*10000L)/306001L;

 *da=(double)(b-d-z-((e*153L)/5L))+jd;
 if ( e<=13L )	*mo=(int)(e-1L);
 else		*mo=(int)(e-13L);

 *ye=(int)(c-4716L);
 if ( *mo<=2 )	(*ye)++;
}

int get_easter_day(int year)
{
 int	x,a,b,c,d,e,f,g,h,i,k,l,m,p;
 x=year;

 a=x%19;
 b=x/100,c=x%100;
 d=b/4,e=b%4;
 f=(b+8)/25;
 g=(b-f+1)/3;
 h=(19*a+b-d-g+15)%30;
 i=c/4,k=c%4;
 l=(32+2*e+2*i-h-k)%7;
 m=(a+11*h+22*l)/451;
 p=h+l-7*m+22;
 return(p);
}
                                                 
fitsh-0.9.2/libastro/output.c0000644000175000017500000000273411236271126014605 0ustar  apalapal/*****************************************************************************/
/* output.c 								     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Prints sexagesimal-formatted angle into a string.			     */
/* This part of the library (output.[ch]) is standalone!		     */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* (c) 2001, 2006; Pal, A. (apal@szofi.elte.hu).			     */
/*****************************************************************************/

#include 
#include 
#include 

#include 

/*****************************************************************************/

char *strdeg(char *buff,double a,int dl,int prec,int type)
{
 int	i,l;
 char	wb[8];
 double	x;

 if ( (type&STRDEG_SIGN) && a>=0.0 )	*buff='+',buff++;
 if ( a<0.0 )				*buff='-',buff++,a=-a;
 for ( l=0 ; l
0 && a<10.0 ) sprintf(wb,"0%%.%df",prec); else sprintf(wb,"%%.%df",prec); sprintf(buff,wb,a); buff+=strlen(buff); return(buff); } /*****************************************************************************/ fitsh-0.9.2/libastro/astro.c0000644000175000017500000000226011236270777014402 0ustar apalapal/*****************************************************************************/ /* astro.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Global constants used by other modules. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 2003-2006; Pal, A. (apal@szofi.elte.hu). */ /*****************************************************************************/ #include /*****************************************************************************/ #include /*****************************************************************************/ const double au_km = 149597870.0; const double r_earth_equ = 6378.14; const double r_earth_pol = 6356.76; const double r_moon = 1738.0; const double r_sun = 696000.0; const double m_mercury = 1.66019749e-7, m_venus = 2.44806226e-6, m_earth = 3.00374072e-6, m_mars = 3.22742996e-7, m_jupiter = 0.954638698e-3, m_saturn = 0.285838546e-3, m_uranus = 0.436664119e-4, m_neptune = 0.515053396e-4; /*****************************************************************************/ fitsh-0.9.2/README0000644000175000017500000001002112771631024012130 0ustar apalapalFITSH - a software package for astronomical image processing - version 0.9.2 **************************************************************************** This software package provides a set of independent binary programs (tasks) that are designed for execution from a UNIX command line shell or shell script. Each of these tasks performs a specific operation (e.g. transforming an image to another reference frame, search and identifiy stars or other point-like sources, do photometry, transform/display a FITS image to a popular graphics format, ...) while the details of a certain operation are specified via command switches and arguments. Therefore this package does not need any higher level operating environment than a standard UNIX shell, however, processing the related data might require a little more knowledge of the used shell itself (the related documentation and examples found in this page use the bash shell). Additionally, some of the processing steps might require minor or basic operations performed with other tools like awk or text processing utilities (sort, uniq, paste, ...). For a brief summary about the individual tasks, check the ``Tasks'' section of the web page of the project, namely at http://fitsh.net/task Supported systems and requirements ---------------------------------- Actually, the program has been developed under GNU/Linux (Debian, i386 and amd64), and it also tested and seems to work properly on Sun/SunOS, PC/NetBSD and Mac/OSX systems as well. The Mac/OSX port has been tested under the version 10.6.8 (Snow Leopard) with its default GCC (gcc-4.2.1). However, please note that the primary development platform of the package is Debian GNU/Linux, thus compilation-time warnings might occur on other operating systems. Documentation ------------- The FITSH tasks have a built-in self-explaining reference documentation system, that can be asked using the --long-help option. The format of this long-help output is a standard to the `help2man` utility, with which nice manual pages can be generated easily (and then these can be converted to PDF or PostScript as well). See also the `make help2man` Makefile-target: this target builds the manual pages as well as converts them into PostScript format if the utilities `help2man` and `groff` are installed properly on the host operating system. The web page of the project (http://fitsh.net) also displays these manual pages as well as one can find further, completely working examples. Copyright --------- This software was written by Andras Pal . The FITSH package is a free software, available under the terms of GPLv3 (see ./COPYING for a full license). 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. Bug reports, comments and ideas are welcomed, send these to Andras Pal . See also the web page of the project, found at http://fitsh.net/. That page gathers information about the program (including documentation and examples), this is the primary download source of the package itself, and additionally, serves a public forum for the program users in various topics. Acknowledgements ----------------- The current development of the FITSH package is supported by the Hungarian Academy of Sciences via the grant LP2012-31. Earlier versions of the code have been developed for the Hungarian-made Automated Telescope (HAT) project. Further development has supported by the ESA PECS grant no. PECS 98073. If you find the FITSH package useful in your research, please cite the paper 2012MNRAS.421.1825P (http://adsabs.harvard.edu/abs/2012MNRAS.421.1825P) as "P\'al, A. 2012, MNRAS, 421, 1825". fitsh-0.9.2/misc/0000755000175000017500000000000012771621310012206 5ustar apalapalfitsh-0.9.2/misc/deb/0000755000175000017500000000000012772015305012742 5ustar apalapalfitsh-0.9.2/misc/deb/fitsh.control0000644000175000017500000000301712772015305015462 0ustar apalapalPackage: fitsh Version: __VERSION__ Section: utils Priority: optional Architecture: __ARCH__ Depends: libc6 (>= 2.3.2) Installed-Size: __INSTALLED_SIZE__ Maintainer: Andras Pal Source: fitsh Description: FITSH - a software package for astronomical image processing This software package provides independent binary programs (so called tasks) which performs various steps of astronomical image reduction and data processing. These tasks are designed for execution from a UNIX command line shell or shell script. Each of these tasks performs a specific operation (e.g. transforming an image to another reference frame, search and identifiy stars or other point-like sources, do photometry, transform/display a FITS image to a popular graphics format, ...) while the details of a certain operation are specified via command switches and arguments. Therefore this package does not need any higher level operating environment than a standard UNIX shell, however, processing the related data might require a little more knowledge of the used shell itself. If you find this program useful in your research, please cite 2012MNRAS.421.1825P as "2012, MNRAS, 421, 1825". See also the web page of the project, found at http://fitsh.net/. That page gathers information about the program (including documentation and examples), this is the primary download source of the package itself, and additionally, serves a public forum for the program users in various topics. Bug reports, comments and ideas are welcomed! fitsh-0.9.2/misc/deb/fitsh.list0000644000175000017500000000260612771623343014766 0ustar apalapal./src/fiarith usr/bin/fiarith ./src/ficalib usr/bin/ficalib ./src/ficombine usr/bin/ficombine ./src/ficonv usr/bin/ficonv ./src/fiheader usr/bin/fiheader ./src/fiign usr/bin/fiign ./src/fiinfo usr/bin/fiinfo ./src/fiphot usr/bin/fiphot ./src/firandom usr/bin/firandom ./src/fistar usr/bin/fistar ./src/fitrans usr/bin/fitrans ./src/grcollect usr/bin/grcollect ./src/grmatch usr/bin/grmatch ./src/grtrans usr/bin/grtrans ./src/lfit usr/bin/lfit ./src/linear.so usr/lib/fitsh/lfit/linear.so ./doc/help2man/fiarith.1.gz usr/share/man/man1/fiarith.1.gz ./doc/help2man/ficalib.1.gz usr/share/man/man1/ficalib.1.gz ./doc/help2man/ficombine.1.gz usr/share/man/man1/ficombine.1.gz ./doc/help2man/ficonv.1.gz usr/share/man/man1/ficonv.1.gz ./doc/help2man/fiheader.1.gz usr/share/man/man1/fiheader.1.gz ./doc/help2man/fiign.1.gz usr/share/man/man1/fiign.1.gz ./doc/help2man/fiinfo.1.gz usr/share/man/man1/fiinfo.1.gz ./doc/help2man/fiphot.1.gz usr/share/man/man1/fiphot.1.gz ./doc/help2man/firandom.1.gz usr/share/man/man1/firandom.1.gz ./doc/help2man/fistar.1.gz usr/share/man/man1/fistar.1.gz ./doc/help2man/fitrans.1.gz usr/share/man/man1/fitrans.1.gz ./doc/help2man/grcollect.1.gz usr/share/man/man1/grcollect.1.gz ./doc/help2man/grmatch.1.gz usr/share/man/man1/grmatch.1.gz ./doc/help2man/grtrans.1.gz usr/share/man/man1/grtrans.1.gz ./doc/help2man/lfit.1.gz usr/share/man/man1/lfit.1.gz fitsh-0.9.2/Makefile.in0000644000175000017500000002252012772016205013323 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ INSTALL=@INSTALL@ .PHONY: all install \ libfits libpsn libastro librandom src doc \ info html pdf ps dvi \ install install-strip \ install-info install-html install-dvi install-pdf install-ps \ help2man man \ uninstall \ clean distclean mostlyclean maintainter-clean TAGS \ deb deb-fitsh DEB_VERSION = @DEB_VERSION@ DEB_ARCH = @DEB_ARCH@ DPKG_DEB = @DPKG_DEB@ GZIP = @GZIP@ datarootdir = @datarootdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ mandir = @mandir@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ infodir = @infodir@ docdir = @docdir@ htmldir = @htmldir@ dvidir = @dvidir@ pdfdir = @pdfdir@ psdir = @psdir@ DLEXT = @DLEXT@ HELP2MAN = @HELP2MAN@ ROFF = @ROFF@ MAN = @MAN@ DVIPS = @DVIPS@ ARCH_VERSION = $(DEB_VERSION) DIST = fitsh-$(ARCH_VERSION) DEB=misc/deb all: src libastro: $(MAKE) -C libastro libfits: $(MAKE) -C libfits libpsn: $(MAKE) -C libpsn librandom: $(MAKE) -C librandom src: libastro libfits libpsn librandom $(MAKE) -C src doc: $(MAKE) -C doc clean: $(MAKE) -C libastro clean $(MAKE) -C libfits clean $(MAKE) -C libpsn clean $(MAKE) -C librandom clean $(MAKE) -C src clean $(MAKE) -C doc clean rm -f $(DIST).tar.gz rm -f *.deb distclean: clean rm -f -r autom4te.cache rm -f ./config.status ./config.log rm -f ./Makefile rm -f ./config.h rm -f ./libastro/Makefile rm -f ./libfits/Makefile rm -f ./librandom/Makefile rm -f ./libpsn/Makefile rm -f ./src/Makefile rm -f ./src/index/Makefile rm -f ./src/io/Makefile rm -f ./src/link/Makefile rm -f ./src/math/Makefile rm -f ./src/math/dft/Makefile rm -f ./src/math/elliptic/Makefile rm -f ./src/math/elliptic/Makefile rm -f ./src/math/expint/Makefile rm -f ./src/math/fit/Makefile rm -f ./src/math/intersec/Makefile rm -f ./src/math/spline/Makefile rm -f ./src/parallel/Makefile rm -f ./src/psn/Makefile rm -f ./doc/Makefile rm -f ./doc/examples/Makefile rm -f ./doc/examples/firandom/Makefile install: src $(INSTALL) -d $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/fiarith $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/ficalib $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/ficombine $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/ficonv $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/fiheader $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/fiign $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/fiinfo $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/fiphot $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/firandom $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/fistar $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/fitrans $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/grcollect $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/grmatch $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/grtrans $(DESTDIR)${bindir} $(INSTALL) -m 0755 ./src/lfit $(DESTDIR)${bindir} $(INSTALL) -d $(DESTDIR)${libdir}/fitsh $(INSTALL) -d $(DESTDIR)${libdir}/fitsh/lfit $(INSTALL) -m 0644 ./src/linear.$(DLEXT) $(DESTDIR)${libdir}/fitsh/lfit $(INSTALL) -d $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/fiarith.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/ficalib.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/ficombine.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/ficonv.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/fiheader.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/fiign.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/fiinfo.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/fiphot.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/firandom.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/fistar.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/fitrans.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/grcollect.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/grmatch.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/grtrans.1.gz $(DESTDIR)${mandir}/man1 $(INSTALL) -m 0644 ./man/lfit.1.gz $(DESTDIR)${mandir}/man1 uninstall: rm -f ${bindir}/fiarith rm -f ${bindir}/ficalib rm -f ${bindir}/ficombine rm -f ${bindir}/ficonv rm -f ${bindir}/fiheader rm -f ${bindir}/fiign rm -f ${bindir}/fiinfo rm -f ${bindir}/fiphot rm -f ${bindir}/firandom rm -f ${bindir}/fistar rm -f ${bindir}/fitrans rm -f ${bindir}/grcollect rm -f ${bindir}/grmatch rm -f ${bindir}/grtrans rm -f ${bindir}/lfit rm -f ${libdir}/fitsh/lfit/linear.$(DLEXT) rm -f ${mandir}/man1/fiarith.1.gz rm -f ${mandir}/man1/ficalib.1.gz rm -f ${mandir}/man1/ficombine.1.gz rm -f ${mandir}/man1/ficonv.1.gz rm -f ${mandir}/man1/fiheader.1.gz rm -f ${mandir}/man1/fiign.1.gz rm -f ${mandir}/man1/fiinfo.1.gz rm -f ${mandir}/man1/fiphot.1.gz rm -f ${mandir}/man1/firandom.1.gz rm -f ${mandir}/man1/fistar.1.gz rm -f ${mandir}/man1/fitrans.1.gz rm -f ${mandir}/man1/grcollect.1.gz rm -f ${mandir}/man1/grmatch.1.gz rm -f ${mandir}/man1/grtrans.1.gz rm -f ${mandir}/man1/lfit.1.gz HELP2MAN_LIST=fiarith ficalib ficombine ficonv fiheader fiign fiinfo fiphot firandom fistar fitrans grcollect grmatch grtrans lfit help2man: src test -d ./doc/help2man || mkdir ./doc/help2man cat ./doc/man.brief | while read b name; do $(HELP2MAN) -n "$$name" -N -h --long-help ./src/$$b > ./doc/help2man/$$b.1; $(GZIP) -f ./doc/help2man/$$b.1; done man: help2man mkdir -p $(MAN) for b in $(HELP2MAN_LIST); do cp -p ./doc/help2man/$$b.1.gz $(MAN); done dist: rm -f -r $(DIST) mkdir $(DIST) mkdir $(DIST)/doc cp -p doc/Makefile.in $(DIST)/doc mkdir $(DIST)/doc/examples cp -p doc/examples/Makefile.in $(DIST)/doc/examples mkdir $(DIST)/doc/examples/firandom cp -p doc/examples/firandom/Makefile.in $(DIST)/doc/examples/firandom mkdir $(DIST)/include mkdir $(DIST)/include/astro cp -p include/astro/*.[ch] $(DIST)/include/astro mkdir $(DIST)/include/fits cp -p include/fits/*.[ch] $(DIST)/include/fits mkdir $(DIST)/include/lfit cp -p include/lfit/*.[ch] $(DIST)/include/lfit mkdir $(DIST)/include/psn cp -p include/psn/*.[ch] $(DIST)/include/psn mkdir $(DIST)/include/random cp -p include/random/*.[ch] $(DIST)/include/random mkdir $(DIST)/libastro cp -p libastro/*.[ch] libastro/Makefile.in $(DIST)/libastro mkdir $(DIST)/libfits cp -p libfits/*.[ch] libfits/Makefile.in $(DIST)/libfits mkdir $(DIST)/librandom cp -p librandom/*.[ch] librandom/Makefile.in $(DIST)/librandom mkdir $(DIST)/libpsn cp -p libpsn/*.[ch] libpsn/Makefile.in $(DIST)/libpsn mkdir $(DIST)/src cp -p src/*.[ch] src/Makefile.in $(DIST)/src mkdir $(DIST)/src/index cp -p src/index/*.[ch] src/index/Makefile.in $(DIST)/src/index mkdir $(DIST)/src/io cp -p src/io/*.[ch] src/io/Makefile.in $(DIST)/src/io mkdir $(DIST)/src/link cp -p src/link/*.[ch] src/link/Makefile.in $(DIST)/src/link mkdir $(DIST)/src/math cp -p src/math/*.[ch] src/math/Makefile.in $(DIST)/src/math mkdir $(DIST)/src/math/dft cp -p src/math/dft/*.[ch] src/math/dft/Makefile.in $(DIST)/src/math/dft mkdir $(DIST)/src/math/elliptic cp -p src/math/elliptic/*.[ch] src/math/elliptic/Makefile.in $(DIST)/src/math/elliptic mkdir $(DIST)/src/math/expint cp -p src/math/expint/*.[ch] src/math/expint/Makefile.in $(DIST)/src/math/expint mkdir $(DIST)/src/math/fit cp -p src/math/fit/*.[ch] src/math/fit/Makefile.in $(DIST)/src/math/fit mkdir $(DIST)/src/math/intersec cp -p src/math/intersec/*.[ch] src/math/intersec/Makefile.in $(DIST)/src/math/intersec mkdir $(DIST)/src/math/spline cp -p src/math/spline/*.[ch] src/math/spline/Makefile.in $(DIST)/src/math/spline mkdir $(DIST)/src/psn cp -p src/psn/*.[ch] src/psn/Makefile.in $(DIST)/src/psn mkdir $(DIST)/man cp -p man/*.1.gz $(DIST)/man mkdir $(DIST)/misc mkdir $(DIST)/misc/deb cp -p misc/deb/fitsh.control misc/deb/fitsh.list $(DIST)/misc/deb cp -p AUTHORS CHANGELOG COPYING INSTALL README VERSION $(DIST) cp -p ./configure configure.ac configure.mingw32 configure.mingw64 ./prepare $(DIST) cp -p Makefile.in config.h.in $(DIST) tar czf $(DIST).tar.gz $(DIST) rm -f -r $(DIST) deb: deb-fitsh deb-fitsh: src help2man rm -f -r $(DEB)/fitsh mkdir -p $(DEB)/fitsh $(DEB)/fitsh/DEBIAN mkdir -p $(DEB)/fitsh $(DEB)/fitsh/usr/bin $(DEB)/fitsh/usr/lib/fitsh/lfit $(DEB)/fitsh/usr/share/man/man1 $(DEB)/fitsh/usr/share/info $(DEB)/fitsh/usr/share/doc/fitsh cat $(DEB)/fitsh.list | while read file target ; do \ cp $$file $(DEB)/fitsh/$$target ; \ done cp README $(DEB)/fitsh/usr/share/doc/fitsh/ gzip $(DEB)/fitsh/usr/share/doc/fitsh/README cp AUTHORS $(DEB)/fitsh/usr/share/doc/fitsh/ gzip $(DEB)/fitsh/usr/share/doc/fitsh/AUTHORS cat $(DEB)/fitsh.control | \ sed -e "s/__ARCH__/$(DEB_ARCH)/" \ -e "s/__VERSION__/$(DEB_VERSION)/" \ -e "s/__INSTALLED_SIZE__/`du -k -s --exclude DEBIAN $(DEB)/fitsh | awk '{ print $$1; }'`/" > $(DEB)/fitsh/DEBIAN/control for f in `find $(DEB)/fitsh` ; do \ o=`echo $$f | sed 's/deb\/fitsh\///'` ; \ if [ -f "$$f" -a `dirname "$$f"` != $(DEB)/fitsh/DEBIAN ] ; then \ m=`md5sum $$f | awk '{ print $$1; }'` ; \ echo $$m $$o ; \ fi ; \ done > $(DEB)/fitsh/DEBIAN/md5sums $(DPKG_DEB) --build $(DEB)/fitsh fitsh_$(DEB_VERSION)_$(DEB_ARCH).deb rm -f -r $(DEB)/fitsh fitsh-0.9.2/include/0000755000175000017500000000000011657725346012716 5ustar apalapalfitsh-0.9.2/include/fits/0000755000175000017500000000000011325431425013643 5ustar apalapalfitsh-0.9.2/include/fits/fits.h0000644000175000017500000011021011301525343014751 0ustar apalapal/*****************************************************************************/ /* fits.h */ /*****************************************************************************/ #ifndef __FITS_H_INCLUDED #define __FITS_H_INCLUDED 1 /*****************************************************************************/ #include /* (FILE *) */ /*****************************************************************************/ /* These values are highly parts of the FITS standard, never change them */ #define FITS_TAPE_BLOCKSIZE 2880 #define FITS_TAPE_CARDIMAGESIZE 80 /*****************************************************************************/ #define FITS_MAX_NAXIS 17 /* maximum image dimension */ /* if you need more, change this */ /* and recompile _all_ stuff. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define FITS_EMPTY 0 /* Empty (80 spaces) */ #define FITS_VSTR 1 /* Normal string, 'quoted'... */ #define FITS_VBOOLEAN 2 /* Boolean (stored as int) */ /* e.g: SIMPLE = T, EXTEND = F */ #define FITS_VINT 3 /* Integer (stored as int) */ #define FITS_VDOUBLE 4 /* Real (stored as double) */ #define FITS_VCOMMENT 5 /* Commentary text w/wo keyword */ #define FITS_SH_FIRST 0 /* See fits_set_header_any() */ #define FITS_SH_LAST 1 #define FITS_SH_ADD 2 #define FITS_SH_INSERT 3 #define FITS_SH_FORCEFIRST 4 #define FITS_SH_BEGIN 5 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define FITSERR_OPEN 1 #define FITSERR_ALLOC 2 #define FITSERR_FRAME_MISSING 3 #define FITSERR_FRAME_AMBIG 4 #define FITSERR_FRAME_INVALID 5 #define FITSERR_IMAGE 6 #define FITSERR_SCALE 7 /****************************************************************************** The FITS header element sturcure: describes one header element: - name: the keyword of the card image (in the standard FITS files, it should not have a lenght more than 8 characters (excluding the trailing zero); - comment: the comment for the given image (the string after the first '/'; - type: the type of the value stored in the given card image, see the declarations of FITS_EMPTY, ...; - vstr: if type==FITS_VSTR or FITS_VCOMMENT, the string is stored in vstr (including the trailing zero and excluding the single quotation marks); - vint: if type==FITS_VINT or FITS_VBOOLEAN the data is here; - vdouble: if type==FITS_VDOUBLE, the data is here. The FITS header structure: describes a whole header: - hdrs: array of the header elements - nhdr: number of the header elements (trailing 'END' is not included!) - ahdr: the allocated memory for headers (should not be less than 'nhdr') ******************************************************************************/ typedef struct { char name[16]; char comment[80]; int vtype; char vstr[80]; int vint; double vdouble; } fitsheader; typedef struct /* FITS main/extension header information: */ { fitsheader *hdrs; /* - header array ('END' is not included!) */ int nhdr; /* - number of headers */ int ahdr; /* - currently allocated entries for 'hdrs' */ } fitsheaderset; /*****************************************************************************/ typedef struct { double bscale; double bzero; } fitsscale; typedef struct { int sx,sy; /* The fits file contanis an image: */ int bit; /* with a size 'sx' x 'sy', readed at */ double **data; /* the depth 'bit' and stored in 'data' */ int dim; /* if NAXIS != 2... */ int naxis[FITS_MAX_NAXIS]; /* values of NAXIS[1-4] */ void *vdata; void *allocdata; /* alloc. image (freed if not NULL) */ fitsscale curr,read; /* scaling and bias values */ } fitsimage; typedef struct /* Fields: ASCII (Text) table */ { int colindex; /* value of TBCOLn - 1 */ char format[12]; /* value of TFORMn */ fitsscale scale; /* values of TSCALn and TZEROn */ char type[32]; /* value of TTYPEn */ char unit[32]; /* value of TUNITn */ char null[32]; /* value of TNULLn */ } fitstfield; typedef struct { int nrow; /* value of NAXIS2 */ int rowsize; /* value of NAXIS1 */ int ntfield; /* value of TFIELDS */ fitstfield *tfields; unsigned char **data; void *allocdata; } fitsttable; /* Definitions of valid TFORM data types in BINTABLE extensions */ /* See [1], p43., Table 8.5 */ #define FTF_LOGICAL ('L') #define FTF_BIT ('X') #define FTF_BYTE ('B') #define FTF_UINT8 FTF_BYTE #define FTF_SHORT ('I') #define FTF_INT16 FTF_SHORT #define FTF_LONG ('J') #define FTF_INT32 FTF_LONG #define FTF_LONGLONG ('K') #define FTF_INT64 FTF_LONGLONG #define FTF_STRING ('A') #define FTF_CHARACTER FTF_STRING #define FTF_CHAR FTF_STRING #define FTF_FLOAT ('E') #define FTF_REAL32 FTF_FLOAT #define FTF_DOUBLE ('D') #define FTF_REAL64 FTF_DOUBLE #define FTF_FLOATCOMPLEX ('C') #define FTF_COMPLEX32 FTF_FLOATCOMPLEX #define FTF_DOUBLECOMPLEX ('M') #define FTF_COMPLEX64 FTF_DOUBLECOMPLEX #define FTF_ARRAY ('P') typedef struct /* Fields: binary table */ { int form; /* derived from TFORMn (see FTF_*) */ int repeat; /* derived from TFORMn */ int basesize; /* derived from 'form' */ int offset; /* derived from previous values */ fitsscale scale; /* values of TSCALn and TZEROn */ char type[32]; /* value of TTYPEn */ char unit[32]; /* value of TUNITn */ char null[32]; /* value of TNULLn */ } fitsbfield; typedef struct { int nrow; /* value of NAXIS2 */ int rowsize; /* value of NAXIS1 */ int nbfield; /* value of TFIELDS */ fitsbfield *bfields; int pcount; /* value of PCOUNT */ unsigned char **data; void *allocdata; } fitsbtable; typedef union { fitsimage i; fitsttable t; fitsbtable b; } fitsextensiondata; #define FITS_EXT_IMAGE 1 #define FITS_EXT_TABLE 2 #define FITS_EXT_BINTABLE 3 typedef struct { int type; fitsheaderset header; fitsextensiondata x; } fitsextension; /****************************************************************************** The complete FITS data: - (fitsheaderset)header: the complete primary header of the FITS data - (fitsimage)i: the primary image, if any (so i.vdata != NULL). - (fitsextension[])xtns: array of extensions - (int)nxtn: number of extensions - length: if the FITS contains something else than an image (so, the header doesn't have appropriate NAXIS, BITPIX, NAXIS1 and NAXIS2 fields) - rawdata: the data in the FITS file, a dynamically allocated array of 'length' bytes ******************************************************************************/ typedef struct { fitsheaderset header; fitsimage i; fitsextension *xtns; int nxtn; int length; char *rawdata; } fits; /*****************************************************************************/ /* Function prototypes */ /*****************************************************************************/ /****************************************************************************** Note that I/O routines with trailing `_cb` in their name has the same functionality as the originating functions with the appropriate file stream (FILE *fr or FILE *fw), but these functions - instead of reading from or write to file streams - are using callback functions for reading / writing. The function cb_read(void *param,void *dst,int length) is for reading 'length' bytes to the buffer 'dst', while the optional parameter 'param' is passed directy at each call. This function should return a negative number on error, 0 when end-of-input-data is reached, otherwise the total number of bytes read. If 'dst' is NULL, the function _must_ jump over the next 'length' bytes of the input data and should not fail (therefore, in this case the callback should behave like lseek() and fseek() calls with SEEK_CUR argument; but here the value of 'length' is always non-negative). The function cb_write(void *param,void *src,int length) is for writing 'length' bytes from the buffer 'src', while the optional parameter 'param' is passed directly at each call. This function should return a negative integer on error, otherwise the total number of bytes written. If 'src' is NULL, the function can do anything, e.g. it can return 0 (0 bytes has been written from NULL). For an impementation, see fits_cb_read() and fits_cb_write() in the module fits-common.c. These functions do reading/writing from file streams: the parameter 'param' is a (void *)-casted form of (FILE *) and these functions cal fread(), fseek() and fwrite() directly. This whole callback-stuff is the abstraction of the underlying I/O of FITS data handling. In practice, it can also be used for reading/writing FITS data from/to network sockets, pipes and also for dumping the whole FITS data into a machine-independent format (especially in the native FITS binary representation) in the conventional memory. ******************************************************************************/ /* fits_create(): Creates an empty FITS descriptor (with no header, no data and no rawdata).*/ fits * fits_create(void); /* fits_duplicate(): Duplicates the FITS 'img' (even when it is not an image). */ fits * fits_duplicate(fits *img); /* fits_duplicate_empty(): Duplicates the FITS 'img' and if it was an image, fills the array 'data' with zeros. */ fits * fits_duplicate_empty(fits *img); /* fits_free_image(): Frees the array 'data' of the FITS 'img', if it was an image. After the release of the array, it sets the 'data' to NULL and resets 'sx' and 'sy'.*/ void fits_free_image(fits *img); /* fits_free(): Frees the whole FITS 'img'. */ void fits_free(fits *img); /* fits_tapeblock_size(): Returns the required size to store 'size' bytes in FITS tape blocks. Practically, this function round the value of 'size' up to the nearest multiple of FITS_TAPE_BLOCKSIZE, which is 2880. */ int fits_tapeblock_size(int size); /* fits-header.c */ /*********************************************************/ /* fits_headerset_reset(): Resets the headerset data (set all values to NULL and 0). Must be called before any fits_headerset_...() call if local automatic header structures want to be used. The function doesn't do any memory release. */ int fits_headerset_reset(fitsheaderset *header); /* fits_headerset_duplicate(): Duplicates the headerset 'act'. */ int fits_headerset_duplicate(fitsheaderset *r,fitsheaderset *act); /* fits_headerset_free(): Releases and resets the headerset data 'header'. */ int fits_headerset_free(fitsheaderset *header); /* fits_headerset_read(), fits_headerset_write(), fits_headerset_read_cb(), fits_headerset_write_cb(): Reads/writes the complete headerset from/to 'fr'/'fw' or via callback. */ int fits_headerset_read(FILE *fr,fitsheaderset *header); int fits_headerset_write(FILE *fw,fitsheaderset *header); int fits_headerset_read_cb(int (*cb_read)(void *,void *,int), void *param,fitsheaderset *header); int fits_headerset_write_cb(int (*cb_write)(void *,void *,int), void *param,fitsheaderset *header); /* fits_headerset_get_count(): Counts how many header elements in the headerset have a name of 'hdr'. The comparison is case-sensitive, so, according to the FITS standards, the 'hdr' should be an uppercase-string. */ int fits_headerset_get_count(fitsheaderset *header,char *hdr); /* fits_headerset_get_id(): Returns the array index of the 'cnt'th copy of the header 'hdr' in the headerset 'header'. The 'cnt' should be between zero (the first such header) and fits_headerset_get_count(header,hdr)-1 (the last such header). Otherwise, or if the header 'hdr' doesn't exist in the headerset, the function returns a negative value. */ int fits_headerset_get_id(fitsheaderset *header,char *hdr,int cnt); /* fits_headerset_get_header(), fits_headerset_get_uniq_header(): Returns the pointer to the header structure of 'cnt'th copy of the header 'hdr' in the headerset 'header'. This function does almost the same what the fits_headerset_get_id does, but returns the pointer itself instead of the array index. If the header 'hdr' doesn't exist in the headerset or 'cnt' is negative or larger than fits_headerset_get_count(), it returns NULL. The function fits_headerset_get_uniq_header() works like above but assumes the header element named 'hdr' to be unique. So if there is more than one header element with this name, this function also returns NULL. */ fitsheader * fits_headerset_get_header(fitsheaderset *header, char *hdr,int cnt); fitsheader * fits_headerset_get_uniq_header(fitsheaderset *header, char *hdr); /* fits_headerset_get_as_double(): Reads the numerical value from the first occurence of the header element named "hdr". If 'is_ambigous_allowed' is false (zero), just one copy of the header 'hdr' is allowed (see also fits_headerset_get_uniq_header()). Otherwise the function interprets the first occurence of the header element named "hdr". If the type of the header field with such name is an integer or real (consequently, numerical), the function converts it to double, stores it in 'ret' and returns zero. In all other cases -- there's no such header element named "hdr", more than one "hdr" exist if 'is_ambigous_allowed' is false, or the header value is not numerical -- the function returns a nonzero value. */ int fits_headerset_get_as_double(fitsheaderset *header, char *hdr,double *ret,int is_ambigous_allowed); /* fits_headerset_append(), fits_headerset_insert(): Low-level functions to append or insert a single header element after or before the headerset 'header'. The pointer to the newly created header element is returned (or NULL if any error occured). */ fitsheader * fits_headerset_append(fitsheaderset *header); fitsheader * fits_headerset_insert(fitsheaderset *header); /* fits_headerset_set_any(): Creates or updates a header element with a name of 'hdr' in the headerset. The behaviour of this function depends on the rule 'rule': - if 'rule' is FITS_SH_FIRST, the function returns a pointer to the first element with the name of 'hdr' or creates a new header field with the name 'hdr' if it didn't exist before the call (and then, the returned pointer points to this newly created header field), - if 'rule' is FITS_SH_LAST, the function returns a pointer to the last occurence of the header with the name of 'hdr' or creates a new header field with the name 'hdr' if it didn't exist before the call, - if 'rule' is FITS_SH_ADD, the function creates a new header field with the name 'hdr' and the returned pointer points to this newly created header field. In all cases, the comment field of the returned header is updated to 'c' if it was non-NULL (otherwise, the comment of the header is not changed or set to NULL if it is a new header). However, this function might have had to be written as a static function (used by the other fits_set_header_*() functions), sometimes it can be useful if low-level or automatic manipulation of the headers is needed in any application. Use it carefully. */ fitsheader * fits_headerset_set_any(fitsheaderset *header, char *hdr,int rule,char *comment); /* fits_headerset_set_[integer,double,string,boolean](): These four routines create or update a header element with the name of "hdr" in the headerset 'header'. The rules described by 'rule' are the same in fits_headerset_set_any(). The structure element vtype is updated (to FITS_VINT, FITS_VDOUBLE, FITS_VSTR or FITS_VBOOLEAN, respectively), and the new value of the field is set. If 'c' is non-NULL, the comment of the given header is updated also. */ int fits_headerset_set_integer(fitsheaderset *header, char *hdr,int rule,int val ,char *comment); int fits_headerset_set_double (fitsheaderset *header, char *hdr,int rule,double val,char *comment); int fits_headerset_set_string (fitsheaderset *header, char *hdr,int rule,char *str ,char *comment); int fits_headerset_set_boolean(fitsheaderset *header, char *hdr,int rule,int vbool ,char *comment); /* fits_headerset_delete(), fits_headerset_delete_all(): The function fits_headerset_delete() deletes the 'k'th occurrence of the header element named "hdr" from the headerset 'header'. The function fits_headerset_delete_all() deletes all occurrences of header elements named "hdr" from the headerset 'header'. */ int fits_headerset_delete(fitsheaderset *header,char *hdr,int k); int fits_headerset_delete_all(fitsheaderset *header,char *hdr); /* fits_headerset_copy(), fits_headerset_merge(): Copies or merges headersets (from 'h2' to 'h1' and from 'h' to 'xh'). */ int fits_headerset_copy(fitsheaderset *h1,fitsheaderset *h2); int fits_headerset_merge(fitsheaderset *xh,fitsheaderset *h, int is_inherit); /* fits_headerset_is_extension(): Checks if the headerset 'header' is an extension header unit or not. If it is not an extension header (so, primary), the function returns 0, otherwise it returns a positive value indicating the type of the extension (see the definitions: FITS_EXT_IMAGE, FITS_EXT_TABLE, FITS_EXT_BINTABLE). */ int fits_headerset_is_extension(fitsheaderset *header); /* fits-table.c */ /**********************************************************/ int fits_table_get_params(fitsheaderset *header,fitsttable *ft); int fits_table_alloc(fitsttable *ft); int fits_table_read(FILE *fr,fitsttable *ft); int fits_table_read_cb(int (*cb_read)(void *,void *,int), void *param,fitsttable *ft); int fits_table_skip(FILE *fr,fitsttable *ft); int fits_table_skip_cb(int (*cb_read)(void *,void *,int), void *param,fitsttable *ft); int fits_table_set_params(fitsheaderset *header,fitsttable *ft); int fits_table_free(fitsttable *ft); int fits_table_write(FILE *fw,fitsttable *ft,int is_pad); int fits_table_write_cb(int (*cb_read)(void *,void *,int), void *param,fitsttable *ft,int is_pad); int fits_table_duplicate(fitsttable *ret,fitsttable *src,int flag); /* fits-bintable.c */ /*******************************************************/ int fits_bintable_form_basesize(int form); char * fits_bintable_form_cname(int form); int fits_bintable_get_params(fitsheaderset *header,fitsbtable *fb); int fits_bintable_create_fields(fitsbtable *fb,int,int nbf,...); int fits_bintable_check_fields(fitsbtable *fb,int nbf,...); int fits_bintable_set_xtr_params(fitsbtable *fb,int n, char *type,char *unit,char *null); int fits_bintable_set_xtr_scale(fitsbtable *fb,int n, double bscale,double bzero); int fits_bintable_alloc(fitsbtable *fb); int fits_bintable_read(FILE *fr,fitsbtable *fb); int fits_bintable_read_cb(int (*cb_read)(void *,void *,int), void *param,fitsbtable *fb); int fits_bintable_skip(FILE *fr,fitsbtable *fb); int fits_bintable_skip_cb(int (*cb_read)(void *,void *,int), void *param,fitsbtable *fb); int fits_bintable_set_offsets(fitsbtable *fb); int fits_bintable_set_params(fitsheaderset *header,fitsbtable *fb); int fits_bintable_free(fitsbtable *fb); int fits_bintable_write(FILE *fw,fitsbtable *fb,int is_pad); int fits_bintable_write_cb(int (*cb_read)(void *,void *,int), void *param,fitsbtable *fb,int is_pad); int fits_bintable_duplicate(fitsbtable *ret,fitsbtable *src,int f); /* fits-image.c */ /**********************************************************/ /* fits_image_alloc(), fits_image_alloc_2d(): Allocates an image (see the '*data' elements of the 'fitsimage' structure) and sets the 'sx' and 'sy' elements to the appropriate values. */ int fits_image_alloc(fitsimage *fi,int sx,int sy); int fits_image_alloc_2d(fitsimage *fi,int sx,int sy); /* fits_image_alloc_3d(): Allocates a cubic image (see the 'vdata' and 'allocdata' elements of the 'fitsimage' structure) and sets the 'dim' and 'naxis' array elements to the appropriate values. The 'sx' and 'sy' elements are also set and the array 'data' points to the first (zeroth) plane in the three dimensional array 'vdata'. To access the data, 'vdata' should be casted to (double ***). */ int fits_image_alloc_3d(fitsimage *fi,int sx,int sy,int sz); /* fits_image_alloc_gen(): Allocates an image with arbitrary dimension 'dim' and with the axis sizes given in the array 'naxis'. The 'sx' and 'sy' elements of the FITS structure are also set to 'naxis[0]' and 'naxis[1]' while the array 'data' points to the first(zeroth) 2 dimensional hyperplane in the multidimensional array 'vdata'. If 'dim' is 2, then 'vdata' and 'data' has the same value. To access the data, 'vdata' should be casted to (double **....**) where the number of asterixes is 'dim'. */ int fits_image_alloc_gen(fitsimage *fi,int dim,int *pnaxis); double ** fits_image_first_layer(void *data,int dim); double * fits_image_first_pixel(void *data,int dim); int fits_image_total_pixels(int dim,int *naxis); void fits_image_free(fitsimage *fi); int fits_image_set_value(fitsimage *fi,double value); int fits_image_reset(fitsimage *fi); /* fits_image_read_line(), fits_image_read_line_cb(): Reads 'sx' elements from the stream 'f'. The input is treated as a type of 'bit' (so, this value should be taken from the header BITPIX before reading) and in all cases, it is converted to real (BITPIX=-64, double) values and stored in 'line'. The number of bytes read is returned, it is always 'sx' times |'bit'/8|. */ int fits_image_read_line(FILE *f,int sx,int bit,double *line); int fits_image_read_line_cb(int (*cb_read)(void *,void *,int), void *param,int sx,int bit,double *line); /* fits_image_get_scale(): Reads the apropriate scaling and bias value from the headerset 'header' using BSCALE and BZERO keywords (if they are present and not ambigous). If there are no such headers (and the header is not corrupted) the function returns 1.0 and 0.0 as scale and bias value. */ int fits_image_get_scale(fitsheaderset *header,fitsimage *fi, double *rbscale,double *rbzero); /* fits_image_get_params(): Tries to interpret the headerset 'header as an image (so, NAXIS is 2, and has a header of BITPIX, NAXIS1 and NAXIS2), and sets the 'bit', 'sx' and 'sy' elments in the FITS structure to the appropriate values. If the header really describes an image, the 'sx', 'sy' and 'bit' parameters are set and the call returns 0. Otherwise, these parameters of the FITS structure are reset (all of them has a value of 0), and the call returns a non-zero value. If in the header of 'img' BSCALE and BZERO keywords are found (see fits_get_scale()), the appropriate values are stroed in in the structure img->read and img->curr also. If there are no such keywords, these parameters are set to 1.0 an 0.0 (see fits_image_get_scale()). */ int fits_image_get_params(fitsheaderset *header,fitsimage *fi); /* fits_image_rescale(): Rescales the image in 'fi' ('fi->vdata) using the scaling and bias parameters in the structure 'fi'->curr. After the rescaling, 'fi'->curr.bscale and 'fi'->curr.bzero are set to 1.0 and 0.0 respectively. The call does not affect and use the values in 'fi'->read. */ int fits_image_rescale(fitsimage *fi); /* fits_image_backscale(): Scales back the image in 'fi' using the scaling and bias parameters 'scale' and 'zero'. These new scaling parameters are also stored in the structure 'fi'->curr while the structure 'fi'->read is not affected. The usual call of this function is something like fits_image_backscale(fi,fi->read.bscale,fi->read.bzero); Note the differece between the scalings 'fi'->curr and 'fi'->read. The former is used by these functions, the latter is exported and imported by the calls fits_image_get_params() and fits_image_set_params(). */ int fits_image_backscale(fitsimage *fi,double scale,double zero); /* fits_image_quantize(): This function rounds the pixels of the image to 'nquantizebit' significant bits. If 'nquantizebit' is zero, pixel values are simply rounded down to the nearest integer (see floor()), while if 'nquantizebit' is negative, the values are rounded down to the nearest multiple of 2^{-nquantizebit}. */ int fits_image_quantize(fitsimage *fi,int nquantizebit); /* fits_image_set_params(): Exports the 'fi'->bit, 'fi'->dim, 'fi'->naxis, 'fi'->read.bscale and 'fi'->read.bzero values into the header elements of the headerset 'header' named BITPIX, NAXIS, NAXIS..., BSCALE and BZERO respectively. */ int fits_image_set_params(fitsheaderset *header,fitsimage *fi); /* fits_image_read(), fits_image_read_cb(): Tries to read the whole image from the stream 'fr' to the 'fi'->vdata array. Before this call, the 'img'->dim, 'img'->naxis[] and 'img'->bit values must be set properly and the 'img'->vdata array must exist (must be allocated).*/ int fits_image_read(FILE *fr,fitsimage *fi); int fits_image_read_cb(int (*cb_read)(void *,void *,int), void *param,fitsimage *fi); /* fits_image_skip(), fits_image_skip_cb(): Seeks the file pointer of 'fr' after the image. */ int fits_image_skip(FILE *fr,fitsimage *fi); int fits_image_skip_cb(int (*cb_read)(void *,void *,int), void *param,fitsimage *fi); /* fits_image_write_line(), fits_image_write_line_cb(): Writes the pixel data 'line' with a size of 'sx' to the stream 'fw'. The data is converted, according to the value of 'bit'. The function returns the number of bytes written to the stream. */ int fits_image_write_line(FILE *fw,int sx,int bit,double *line); int fits_image_write_line_cb(int (*cb_write)(void *,void *,int), void *param,int sx,int bit,double *line); /* fits_image_write(), fits_image_write_cb(): Writes the whole image 'fi' to the stream 'fw'. The function returns the number of bytes written to the stream. The function pads the written data with zeros (to be a multiple of 2880 bytes) if 'is_pad' is true. */ int fits_image_write(FILE *fw,fitsimage *fi,int is_pad); int fits_image_write_cb(int (*cb_write)(void *,void *,int), void *param,fitsimage *fi,int is_pad); /* fits_image_dump(): A new array of doubles is created with the approporiate size and the img->vdata array is copied here, if the FITS image 'fi' contains a valid image (it can have any dimension). If the dumping was successful, the function returns the pointer pointing to the newly allocated array (which can be released with free()), otherwise it returns NULL. */ double * fits_image_dump(fitsimage *fi); /* fits_image_duplicate(): Duplicates the FITS image 'src' (and stores the new image in 'ret' which can be uninitialized before this call). If 'flag' is true, the whole image is copied, otherwise this function fills up the data array (see 'vdata' element of the structure) with zeros. */ int fits_image_duplicate(fitsimage *ret,fitsimage *src,int flag); /* fits_image_bitpix_cname(): Returns a static string which points to a canonincal C-like variable type name which can be assigned to the appropriate bitpix value. Note that if bitpix is 8, it returns "byte" (instead of "char") and if bitpix is 32, it returns "long" even in 64-bit architectures. */ char * fits_image_bitpix_cname(int bitpix); /* fits_image_trim(): Trims a section from the image. The outer pixels are replaced by the value defined by the 'outer' variable. Actually, it works only for 2 dimensional images (otherwise, the function does nothing just return a negative value indicating the error). */ int fits_image_trim(fitsimage *i,int x0,int y0,int nx,int ny,double outer); /* fits-draw.c */ /***********************************************************/ /* fits_image_draw_[pixel,line,circle](): Draw pixels, lines and circles to the image data of the FITS image 'img' with the specified value of 'color'. These routines might be useful in special cases or during debugging. These functions return zero if the drawing was successful, otherwise return a non-zero value. */ int fits_image_draw_pixel(fitsimage *img,int x,int y,double col); int fits_image_draw_line(fitsimage *img,int x,int y,int dx,int dy, double col,int style); int fits_image_draw_circle(fitsimage *img,int x,int y,int r,double col); /* fits_draw_[pixel,line,circle](): The same like above, but the target image is the primary image of the FITS data 'img' (if any). */ int fits_draw_pixel(fits *img,int x,int y,double color); int fits_draw_line(fits *img,int x1,int y1,int x2,int y2,double c,int sty); int fits_draw_circle(fits *img,int x,int y,int r,double color); /* fits-ui.c */ /*************************************************************/ /* fits_basename(): Extract the `basename' of the filename 'name'. If 'name' ends like [] where is a positive integer, this integer is stored in 'retframeno' (if it is not NULL) and a pointer to a truncated name (omitting the trailing [...]) is returned in a static memory area (which cannot be released by free() and may be overwritten by further calls). If the name does not contain any trailing "[...]" string, the function returns the same pointer 'name', and 0 is stored in 'retframeno' (again, if it is not NULL). This function is useful for handling image names like IRAF and ds9 do so. */ char * fits_basename(char *name,int *retframeno); /* fits_header_export_command_line(): Exports the command line argument list described by 'argc','argv' (passed to main(), respectively) into the FITS header of 'img' with the keyword 'kw'. If the whole command line is longer than ~70 characters, the list will be splitted to more card images (all with the same keyword). All nasty characters (parsed by the shell, such wildcards, parentheses, ...) in the command line argument are escaped or the whole argument is quoted */ int fits_header_export_command_line(fits *img, char *kw,char *first,char *prefix, int argc,char *argv[]); /* fits_error(): The fits_error() function returns a string describing the error code passed in the argument 'errcode' which is one of the definied error codes FITSERR_* (see the begining of this header file). */ char * fits_error(int errcode); FILE * fits_file_open(char *name); FILE * fits_file_create(char *name); int fits_file_close(FILE *f); /*****************************************************************************/ int fits_read_extension_table(FILE *fr,fitsextension *xtn); int fits_read_extension_image(FILE *fr,fitsextension *xtn); int fits_read_extension_bintable(FILE *fr,fitsextension *xtn); fits * fits_read_frame_as_extension(FILE *fr,int frameno); fits * fits_seek_frame_to_image(FILE *fr,int frameno); fits * fits_read_frame_to_image(FILE *fr,int frameno); int fits_read_header(FILE *fr,fits *img); int fits_get_header_count(fits *img,char *hdr); int fits_get_header_id(fits *img,char *hdr,int cnt); fitsheader * fits_get_header(fits *img,char *hdr,int cnt); int fits_get_header_as_double(fits *img,char *hdr, double *ret,int is_ambigous_allowed); int fits_get_gain(fits *img,double *gain); /* fits_set_header_any(), ..., fits_set_header_boolean(): These functions are wrappers to fits_headerset_set_any(), ... calls and operate on the primary header unit of the FITS data 'img'. */ fitsheader * fits_set_header_any(fits *img ,char *,int,char *c); int fits_set_header_integer(fits *,char *,int,int val,char *c); int fits_set_header_double (fits *,char *,int,double val,char *c); int fits_set_header_string (fits *,char *,int,char * str,char *c); int fits_set_header_boolean(fits *,char *,int,int val,char *c); int fits_delete_header(fits *img,char *hdr,int cnt); int fits_delete_all_header(fits *img,char *hdr); void fits_copy_full_header(fits *im1,fits *im2); int fits_alloc_image(fits *img,int sx,int sy); int fits_alloc_image_2d(fits *img,int sx,int sy); int fits_alloc_image_3d(fits *img,int sx,int sy,int sz); int fits_alloc_image_gen(fits *img,int dim,int *naxis); int fits_set_image(fits *img,double value); int fits_reset_image(fits *img); int fits_get_scale(fits *img,double *rbscale,double *rbzero); int fits_get_image_params(fits *img); int fits_set_image_params(fits *img); /* fits_set_standard(), fits_set_origin(), fits_set_extend(): Exports the mandatory FITS header 'SIMPLE' and the optional 'ORIGIN' and 'EXTEND' to the primary header of 'img'. The header 'SIMPLE' always has boolean type and true ('T') value. In fits_set_standard() if comment is NULL, it is set to "FITS standard". */ int fits_set_standard(fits *img,char *comment); int fits_set_origin(fits *img,char *origin,char *comment); int fits_set_extend(fits *img,int flag,char *comment); int fits_rescale(fits *img); int fits_backscale(fits *img,double bscale,double bzero); /* fits_read_image_line(), fits_read_image(): Wrappers to fits_image_read_line() and fits_image_read(). The latter call here reads the image into the primary image in the FITS data 'img'. */ int fits_read_image_line(FILE *fr,int sx,int bit,double *line); int fits_read_image(FILE *fr,fits *img); /* fits_read(), fits_read_cb(): Reads a complete FITS file from the stream 'fr' (or using the callback 'cb_read' with the pameter 'param') and tries to interpret it as "intelligent" as possible. If the stream is not a real FITS file, the function returns NULL. Otherwise allocates a new FITS structure, reads all headers and stores it to the 'hdrs' array and after it tries to interpret the header as a header which describes an image. If it is really an image, the function set the 'sx', 'sy' and 'bit' values and reads the complete image to 'data'. If the FITS data contains extensions, they will also be read. If it is not an image, then the data is also read but stored in 'rawdata'. If any of these steps fails, the function returns NULL and the stream position is undefined. */ fits * fits_read(FILE *fr); fits * fits_read_cb(int (*cb_read)(void *,void *,int),void *param); /* fits_read_raw(): Reads a complete FITS file from the stream 'fr'. Even if it was a real image, the data is treated as raw data and stored in 'rawdata'. This is a fast method to read a complete FITS file and read the header structure, so this call might be useful in pipelines which manipulate just some of the header elements. */ fits * fits_read_raw(FILE *fr); /* fits_write_header(): Writes the primary header unit of the FITS data 'img' to the stream 'fw'. This call is equivalent to fits_headerset_write(fw,&img->header). This function also returns the total number of bytes written to the stream. */ int fits_write_header(FILE *fw,fits *img); /* fits_write_image_line(), fits_write_image(): Wrappers to fits_image_write_line() and fits_image_write(). The latter call here writes the primary image in the FITS data 'img'. */ int fits_write_image_line(FILE *fw,int sx,int bit,double *line); int fits_write_image(FILE *fw,fits *img); /* fits_write(), fits_write_cb(), fits_mem_write(): Writes the complete FITS data 'img' (including primary header, primary image and all extensions with their headers) to the stream 'fw'. The function returns the number of bytes written to the stream. */ int fits_write(FILE *fw,fits *img); int fits_write_cb(int (*cb_write)(void *,void *,int), void *param,fits *img); int fits_mem_write(void **buffer,fits *img); double * fits_dump_image_raw(fits *img); fitsextension *fits_extension_add(fits *img,int count); fitsextension *fits_extension_new(fits *img,int type); /*****************************************************************************/ /* fits_cb_read(), fits_cb_write(): Callbacks for reading from and writing to files (FILE *), the parameter 'param' is the file pointer itself casted to void *. */ int fits_cb_read (void *param,void *dst,int length); int fits_cb_write (void *param,void *src,int length); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/include/astro/0000755000175000017500000000000011325431425014026 5ustar apalapalfitsh-0.9.2/include/astro/dtc.h0000644000175000017500000000211410667340126014754 0ustar apalapal/*****************************************************************************/ /* dtc.h */ /*****************************************************************************/ #ifndef __DTC_H_INCLUDED #define __DTC_H_INCLUDED 1 /* read_julian_date(): Reads the current Julian Day using the system function clock(). */ double read_julian_date(void); /* get_julian_date(): Calculates the Julian Day for the day 'ye', 'mo', 'da' (UT, at midnight). */ double get_julian_date(int ye,int mo,int da); /* get_calendar_date(): Converts the Julian Day 'jd' into calendar date and returns it in the integers 'ye', 'mo' and the double 'da'. */ void get_calendar_date(double jd,int *ye,int *mo,double *da); /* get_easter_day(): Returns the day of Easter Sunday in the given year 'year' from 1st of March. If the value returned is greater than 31, Easter Sunday is in April in the given year... */ int get_easter_day(int year); #endif fitsh-0.9.2/include/astro/planets.h0000644000175000017500000000113010674304147015646 0ustar apalapal/*****************************************************************************/ /* planets.h */ /*****************************************************************************/ #ifndef __PLANETS_H_INCLUDED #define __PLANETS_H_INCLUDED 1 /*****************************************************************************/ int get_planet_coords(double jdate, int n, double *rx, double *ry, double *rz); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/include/astro/astro.h0000644000175000017500000000211410674305073015332 0ustar apalapal/*****************************************************************************/ /* astro.h */ /*****************************************************************************/ #ifndef __ASTRO_H_INCLUDED #define __ASTRO_H_INCLUDED 1 /* global constants */ /******************************************************/ extern const double au_km; /* AU/km */ extern const double r_earth_pol,r_earth_equ; /* polar & ekvatorial*/ extern const double r_sun,r_moon; /* in kilometers... */ extern const double m_mercury, /* mass of the planets */ m_venus, /* in solar mass units */ m_earth, m_mars, m_jupiter, m_saturn, m_uranus, m_neptune; /* other header files */ /****************************************************/ #include "cmath.h" #include "dtc.h" #include "earth.h" #include "easpec.h" #include "planets.h" /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/include/astro/cmath.h0000644000175000017500000000372010667340126015302 0ustar apalapal/*****************************************************************************/ /* cmath.h */ /*****************************************************************************/ #ifndef __CMATH_H_INCLUDED #define __CMATH_H_INCLUDED 1 typedef double vector[3]; typedef double matrix[3][3]; /* sina(), cosa(), asina(), acosa(): Funcions like sin(), cos(), asin() and acos(), but all angles are in degs.*/ double sina(double deg); double cosa(double deg); double asina(double s); double acosa(double c); /* rotate(): Rotates (*x,*y) counter-clockwise by the specified angle 'phi' (radians). */ void rotate(double *x,double *y,double phi); /* getpcoords(), get3dpcoords(). Calculates the polar coordinate of the 2d point (x,y) or 3d point (x,y,z). All angles returned are in degrees (not in radians). */ double getpcoords(double x,double y); void get3dpcoords(double x,double y,double z,double *longi,double *latit); /* get_angular_distance(): Calculates the angular separation (in degrees) between the two spherical points (lon1,lat1) and (lon2,lat2). These spherical coordinates should also be specified in degrees. */ double get_angular_distance(double lon1,double lat1,double lon2,double lat2); /* hypot3d(): Calculates the Eucledian distance of the point (x,y,z) from the origin. */ /* solve_kepler_equ(): Solves the Equation of Kepler for the mean anomaly 'm' and eccentricity 'ex'. All angles ('m' and the returned eccentric anomaly) are in radians. */ double solve_kepler_equ(double m,double ex); /* matrix_rotation(): Creates (and stores in 'm') a rotational matrix which rotates by the angle 'phi' (it is in degrees) around the axis 'ax' ('ax' is 0 for x, 1 for y and 2 for z-axis). */ void matrix_rotation(matrix m,int ax,double phi); /* matrix_mul(): Calculates 'm1'*'m2' and stores the result in 'r'. */ void matrix_mul(matrix r,matrix m1,matrix m2); #endif fitsh-0.9.2/include/astro/output.h0000644000175000017500000000160410667340127015546 0ustar apalapal/*****************************************************************************/ /* output.h */ /*****************************************************************************/ #ifndef __OUTPUT_H_INCLUDED #define __OUTPUT_H_INCLUDED 1 #define STRDEG_SIGN 0x01 #define STRDEG_SPACE 0x00 #define STRDEG_COLON 0x02 /* strdeg(): (S)prints the angle 'a' into the buffer 'buff'. The formatting parameters are specified by 'dl', 'prec' and 'type'. Some examples (a=1.65432): dl prec output 0 5 1.65432 2 2 1 39 15.55 1 0 1 39 1 1 1 39.2 If 'type'&STRDEG_SIGN is non-zero the sign '+' is forced to be written for positive angles aslo. If 'type'&STRDEG_COLON is non-zero, the fields are separated with ':' instead of spaces. */ char * strdeg(char *buff,double a,int dl,int prec,int type); #endif fitsh-0.9.2/include/astro/earth.h0000644000175000017500000000113010667340126015302 0ustar apalapal/*****************************************************************************/ /* earth.h */ /*****************************************************************************/ #ifndef __EARTH_H_INCLUDED #define __EARTH_H_INCLUDED 1 /* get_earth_coords(): Returns the heliocentric ecliptical Cartesian coordiantes of the barycentre of the Earth-Moon system at the given instance 'jdate'. The coordinates are in astronomical units. */ int get_earth_coords(double jdate,double *rx,double *ry,double *rz); #endif fitsh-0.9.2/include/astro/easpec.h0000644000175000017500000000454011041346612015440 0ustar apalapal/*****************************************************************************/ /* easpec.h */ /*****************************************************************************/ #ifndef __EASPEC_H_INCLUDED #define __EASPEC_H_INCLUDED 1 /* get_observer_coords(): Calculates the geocentric equatorial Cartesian coordiantes of the observer located at (lon,lat) at the time instance 'jdate'. */ void get_observer_coords(double jdate,double lon,double lat, double *x,double *y,double *z); /* get_sideral_time(): Calculates and returns the sideral time in Greenwih at the instance 'jdate'*/ double get_sideral_time(double jdate); /* get_earth_axis_angle(): Calculates and returns the deviation angle of the rotational axis of the Earth to the norm of the ecliptical plane at the given instance 'jdate'. (Note that this is a non-covariant quantity, so this function might be replaced or changed in future releases of this library...) */ double get_earth_axis_angle(double jdate); /* get_heiocentric_julian_date(): Calculates the heliocentric (not barycentric!) correction for the time instance 'jdate' at the spherical equatorial point ('ra', 'dec'). The corrected time instance is returned. */ double get_heliocentric_julian_date(double jdate,double ra,double dec); /* get_heiocentric_julian_date_epoch(): Same as get_heiocentric_julian_date(), but the coordinates 'ra' and 'dec' are for the epoch (in Julian years) 'epoch'. */ double get_heliocentric_julian_date_epoch(double jdate,double ra,double dec,double y0); /* get_barycentric_julian_date(): Calculates the barycentric correction for the time instance 'jdate' at the spherical equatorial point ('ra', 'dec'). The corrected time instance is returned. */ double get_barycentric_julian_date(double jdate,double ra,double dec); /* get_annular_parallax_correction(): This function calculates the annular parallax correction (i.e. as it would observed from the Sun), for the celestial object located at (ra,dec) (RA, DEC, in degrees) within a distance of 'dis' parsec at the instance 'jdate' (JD). The corrected coordinates are stored in 'rra' and 'rdec'. */ int get_annular_parallax_correction(double jdate,double ra,double dec, double dis,double *rra,double *rdec); #endif fitsh-0.9.2/include/random/0000755000175000017500000000000011657730647014176 5ustar apalapalfitsh-0.9.2/include/random/random.h0000644000175000017500000000160411657730647015630 0ustar apalapal/*****************************************************************************/ /* random.h */ /*****************************************************************************/ #ifndef __RANDOM_H_INCLUDED #define __RANDOM_H_INCLUDED 1 #include /*****************************************************************************/ struct random_state { uint32_t u,v; uint32_t w1,w2; }; int random_state_seed(struct random_state *state,int j); uint32_t random_state_uint32(struct random_state *state); double random_state_double(struct random_state *state); int random_seed(int j); uint32_t random_uint32(void); double random_double(void); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/include/psn/0000755000175000017500000000000011325431425013476 5ustar apalapalfitsh-0.9.2/include/psn/psn.h0000644000175000017500000004605411206340326014455 0ustar apalapal/*****************************************************************************/ /* psn.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* 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 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This library is distributed in the hope that 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, write to the Free Software */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ /*****************************************************************************/ #ifndef __PSN_H_INCLUDED #define __PSN_H_INCLUDED #define PSN_MAX_PREC 32766 /*********** Definition of objects used by the psn_...() routines ************/ /* A term of a PSN sequence: */ typedef struct { short type; short major; short minor; short cache; } psnterm; /* Full information about a PSN sequence: */ typedef struct { psnterm *terms; double *cons; int nterm; int ncon; int ntermalloc; int nconalloc; int nseq; } psn; /* Symbol: variable, operator or function: */ typedef struct { int type; int major; char *name; int minor; } psnsym; /* Properties of an operator or a function (major code, number of input */ /* parameters, percedency and associativity. For operators, TO_PREFIX, */ /* TO_INFIX or TO_SUFFIX should be used in the 'innum' field. */ typedef struct { int major; int argnum; int precedency; int associativity; } psnprop; /* Derivative rules: */ typedef struct { int major; short *oplist; } psndiff; /* Function descriptor, called by psn_double_calc(): */ typedef struct { int major; int (*funct)(double *top_of_the_stack_pointer); } psnfunct; /* Rules for the description of the symbolic evaluation (thus, conversion */ /* of the PSN sequences to any kind of character string), used by */ /* psn_convert_symbolic(): */ typedef struct { int major; char *string; int strength; int affixation; } psnsymeval; /************************ Definition of global constants *********************/ #define T_END 0x00 /* end-of-sequence */ #define T_PAROPEN 0x10 /* parenthesis '(' */ #define T_SEP 0x11 /* separator */ #define T_PARCLOSE 0x12 /* parenthesis ')' */ #define T_CONST 0x20 /* numerical constants */ #define T_SCONST 0x21 /* special constants (=major) */ #define T_VAR 0x22 /* variables */ #define T_STACKVAR 0x23 /* variables on stack */ #define T_OP 0x30 /* operators */ #define T_FN 0x31 /* functions */ /* in PSN sequences these are equivalent to */ /* T_OPs... the differece is between */ /* associativity (functions are left-assoc) */ /* and precedence (maximal for functions) */ #define TO_PREFIX (-1) /* prefix operators (e.g. negation) */ #define TO_INFIX ( 0) /* infix operators (e.g. addition,...) */ #define TO_SUFFIX ( 1) /* suffix operators (e.g. factorial, 'prime')*/ /********* Precedence and associativity definitions, psnprec->assoc **********/ #define ASSOC_LEFT ( 0) /* Left-associated operators (generic) */ #define ASSOC_RIGHT ( 1) /* Right-associated operators (e.g. power:^) */ /***** PSN stack indices, used in the description of derivative rules... *****/ #define SS_REF 128 /* maximum number of stack elements, may be */ /* changed if functions with more than 9 */ /* arguments are expected to be used... */ /* If changed, the whole library should be */ /* re-compiled. */ #define SS_D1 ( -1) /* refers to the top of the derivative stack */ #define SS_D2 ( -2) #define SS_D3 ( -3) #define SS_D4 ( -4) #define SS_D5 ( -5) #define SS_D6 ( -6) #define SS_D7 ( -7) #define SS_D8 ( -8) #define SS_N1 ( -1-SS_REF) /* refers to the top of the stack */ #define SS_N2 (- 2-SS_REF) #define SS_N3 (- 3-SS_REF) #define SS_N4 (- 4-SS_REF) #define SS_N5 (- 5-SS_REF) #define SS_N6 (- 6-SS_REF) #define SS_N7 (- 7-SS_REF) #define SS_N8 (- 8-SS_REF) #define CON_0 (-0-2*SS_REF) /* refers to 0, [T_SCONT, major=0] */ #define CON_1 (-1-2*SS_REF) /* refers to 1, [T_SCONT, major=1] */ #define CON_2 (-2-2*SS_REF) /* refers to 2, [T_SCONT, major=2] */ #define CON_3 (-3-2*SS_REF) /* refers to 3, [T_SCONT, major=3] */ /*************************** Simplification rules ****************************/ #define S_EXP1 (-1) #define S_EXP2 (-2) #define S_EXP3 (-3) #define S_EXP4 (-4) #define S_EXP5 (-5) #define S_EXP6 (-6) #define S_EXP7 (-7) #define S_EXP8 (-8) /***************************** psnerrno values *******************************/ extern int psnerrno; #define PEOK 0 /* Everything is ok... */ #define PEALLOC -1 /* Allocation error */ #define PEINVALID 1 /* Unexpected character or term in a sequence*/ #define PENOTFOUND 2 /* Required function/symbol not found */ #define PEPARSE 3 /* Parse error */ #define PEANALYTICAL 4 /* failure due to analytical error */ #define PENUMERICAL 5 /* failure due to numerical error */ #define PENONDIFF 6 /* Non-differentable operator in a sequence */ #define PEOPTIMIZED 7 /* Sequence is optimized, but it must not be */ #define PEMULTI 8 /* Sequence contains more sub-sequences */ /* Note that the exact meanings of these pre-defined errors are depend on */ /* the function which returned these values or set 'psnerrno'. See the */ /* comments below and the full documentation in ./doc for more details. */ /*************************** Function prototypes *****************************/ /* psn_conv_string(): Encodes the string 'in' using the symbols in 'symtable'. The symbol table 'symtable' should contain a NULL-terminated list of pointers, these pointers point to {0,0,NULL}-terminated lists of symbols. If all operators and alphabetic symbols can be resolved using the symbol table 'symtable', the function returns a pointer to a newly allocated PSN structure, creates the list 'sequence' and initializes the constant table 'cons'. If any of the operators or alphabetic symbols cannot be resolved, the encoding fails and the function returns NULL. If the function returns NULL, the type of the error can be figured out by using the external variable 'psnerrno'. */ psn * psn_conv_string(char *in,psnsym **symtable); /* psn_init(): Initializes the sequence 'seq'. If the initialization is successful, the function returns 0, otherwise the function returns a non-zero value and the type of the error can be found out from comparing it to the PE* pre-defined values. */ int psn_init(psn *seq,psnprop *prop); /* psn_cache_init(), psn_cache_clear(): Initializes and clears the lookup-table (called cache) in the sequence 'seq'. This lookup table is used by psn_double_calc(). If the lookup table was not initialized before the call of psn_double_calc() is not a problem, the first call of psn_double_calc() will do the initialization. Note that in such (almost rare) cases, when the function list 'flist' changes between two calls of psn_double_calc(), the cache must be cleared by psn_cache_clear() or re-initialized by psn_cache_init() before the next call of psn_double_calc(). The cache does not have to be cleared or initialized before calling other funcions than psn_double_calc() which have any argument with the type of (psnfunct*), but some of the functions (e.g. psn_diff(), psn_simplify()) does clear the cache. */ int psn_cache_init(psn *seq,psnfunct *flist); int psn_cache_clear(psn *seq); int psn_cache_search(int major,psnfunct *flist); /* psn_conv(): Re-orders the terms in the sequence 'in' to be a really suffix-notated list of operands and operators. The precendencies of the operators are stored in the {0,0,0}-terminated list 'plist'. If the conversion fails (e.g. due to syntax or parse error), the functions returns NULL, otherwise returns a pointer newly created PSN structure, so the input sequence 'in' is not destroyed. The new sequence inherits the constant table 'cons' of the sequence 'in'. If the function returns NULL, the type of the error can be figured out by using the external variable 'psnerrno'. */ psn * psn_conv(psn *in,psnprop *plist); /* psn_append_term(), psn_append(), psn_cons_append(): Append one or more psnterms or a constant ({type,major,minor,flag}, or the 'nterm'-lenght list 'terms') to the sequence 'seq'. */ void psn_append_term(psn *seq,int type,int major,int minor,int flag); void psn_append(psn *seq,psnterm *terms,int nterm); int psn_cons_append(psn *seq,double con); /* psn_fprint(): Writes the sequence 'seq' to the stream 'f', using the symbol table 'symtable' to resolve the names of symbols (useful for debugging). */ void psn_fprint(FILE *f,psn *seq,psnsym **symtable); /* psn_get_length(): Gets the number of sequence terms of the sequence 'seq'. */ int psn_get_length(psn *seq); /* psn_get_nseq(): Gets how many individual subsequences are stored in the sequence 'seq'. */ int psn_get_nseq(psn *seq); /* psn_get_nstack(): Gets how many terms remain on the stack after the evaluation of the PSN sequence 'pseq'. If the sequence 'pseq' is incosistent, the function returns a negative value. If the optional argument 'ropt' is not NULL, this function stores the number of the optimized elements remaining on the stack (note that this value is always less or equal to the value returned). */ int psn_get_nstack(psn *pseq,int *ropt); /* psn_test(): Tests the integrity of the PSN sequence 'seq': tries to evaluate the expression coded in the sequence 'seq'. If the test fails, the function returns a non-zero value (see PE* values), otherwise -- if the sequence is consistent -- it returs 0. Note that before the call of psn_double_calc(), all sequences should be checked by such a function like psn_test(). To make the evaluation faster, psn_double_calc() does not do any checking and may spectacularly fail (e.g. terminates with segmentation fault, SIGSEGV) if the input sequence is incosistent. */ int psn_test(psn *seq); /* psn_double_calc(): Evaluates the expression coded in the sequence 'seq' using the functions and operands listed in 'functlist'. In this library, this is the only function related to the evaluation of PSN-based sequences and all operands are treated as operands with the type of double. If sequences based on non-real operands (or any other kind of operands which are not having a type of double, e.g. complex variables, vectors, matrices) do want to be used, the appropriate functions like this should be written. After the evaulation, the results are stored in 'result': this array contains `psn_get_nseq(seq)` values. The array 'vars' should contain the appropriate values of the variables (T_VARs). Note that the sequence 'seq' should be checked (e.g. with psn_test()) before calling this function, see also the comments near psn_test(). The functon returns 0, if the caclulation was successful, otherwise it returns a non-zero value (see also the pre-defined error id's: PE*) */ int psn_double_calc(psn *seq,psnfunct *functlist,double *result, double *vars); /* psn_diff(): Caluclates the partial derivative of 'seq' by the the variable 'var_index' using the derivative rules listed in the {0,0,NULL}-terminated list 'diffrules'. If the sequence 'seq' contains a non-differentable operator, or in any other cases, when the requested partial derivative cannot be calculated, the function returns NULL (and the type of the error is indicated by 'psnerrno'), otherwise it returns a pointer which points to a newly created sequence with the desired partial derivative. */ psn * psn_diff(psn *seq,psnprop *plist,psndiff *diffrules,int var_index); /* psn_simplify(): Simplifies the sequence 'seq' using the rules listed in 'rules' and the operator properties listed in 'plist'. If the simplification was successful, the function returns 0, otherwise it returns a non-zero value (see also the PE* values). Operators and functions with pure numerical (T_CONST, T_SCONST) arguments can be evaluated (and replaced by the result) also, if the list of the available functions is passed in the argument 'flist'. If no such simplification is desired, pass NULL in the argument 'flist' to psn_simplift(). */ int psn_simplify(psn *seq,short **rules,psnprop *plist,psnfunct *flist); /* psn_diff_simplify(): This function is subsequent combination of psn_diff() and psn_simplify(). The call also checks the integrity of the resulted PSN sequence using psn_test(), i.e. if the return value is not NULL (a valid PSN sequence), there is no need to call psn_test() after this call. Note that if 'slist' is NULL, the function does not do any simplifications, in this case it is equivalent with psn_diff() and a psn_test() on its result. */ psn *psn_diff_simplify(psn *seq,psnprop *plist,psndiff *dlist, short **slist,psnfunct *flist,int var_index); /* psn_optimize(): Tries to optimize the evaluation of the sequence 'seq'. If the sequence 'seq' has been optimized yet, or the optimization fails, the function returns a non-zero value (see also the PE* values). If the optimization was successful, the function returns 0. */ int psn_optimize(psn *seq); /* psn_replace(): Replaces the operator/function in the sequence 'seq' with the major code 'major' with the sequence 'replacement'. The arguments of the given operator/functions are replaced by the variables (T_VARs) with the codes specified in the array 'varlist'. If 'varlist' is NULL, then the first argument is replaced by the variable with the code 0, the second is replaced by the variable with the code 1 and so on. The function returns a new (replaced) sequence or NULL if something is wrong. */ psn * psn_replace(psn *seq,int major,psn *replacement,int *varlist); /* psn_duplicate(): Duplicates the sequence 'seq_to_be_duplicated'. If the duplication cannot be done, NULL is returned and the type of the error is indicated by 'psnerrno'. */ psn * psn_duplicate(psn *seq_to_be_duplicated); /* psn_concate(): Concatenates the sequences 'seq2' to the sequence 'seq1'. After this call, the sequence 'seq1' will contain `psn_get_nseq(seq1)+psn_get_nseq(seq2)` sub-sequences. If the concatenation was successful, the function returns 0, otherwise it returns a non-zero value and the type of the error can be figured out by using the PE* values. */ int psn_concate(psn *seq1,psn *seq2); /* psn_exctract(): Extracts the nth (0th is the first) sub-sequence from the sequence 'seq' even if it was previously optimized. A pointer to the newly created sequence is returned, if the extraction was successful, otherwise it returns NULL and 'psnerrno' indicates the type of the error. */ psn * psn_extract(psn *seq,int n); /* psn_full_extract(): Extinguishes all optimalizations from the sequence 'seq'. If the procedure was successful, the function returns a pointer to a newly created sequence, otherwise it returns NULL and 'psnerrno' indicates the type of the error occured. */ psn * psn_full_extract(psn *seq); /* psn_convert_symbolic(): Converts the PSN sequence 'seq' to a character string, using the conversion rules defined in the {0,NULL}-terminated array 'syt'. For the variables, the symbols found in 'sym' is used. The numerical values (constants) are inserted into the sequence using sprintf() and the format string 'dformat'. If 'dformat' is NULL, the format string "%g" will be used. The {0,0,0,0}- terminated list of the property-array 'plist' also has to be passed to this function to get the appropriate values of the precedencies of the operators. The symbolic names of the functions and operators might be found in 'sym' are not used in any case. The function returns a newly allocated character stream, which can be released by free(). If any step of the conversation fails (e.g. some of the required conversion rules are not found in 'syt'), the function returns NULL. Note that the 'seq' should contain only one sub-sequence and should not be optimized. If it does not stand for the sequence 'seq', the function also returns NULL. Use psn_extract() and psn_full_extract() to extract any of the sub-sequences from a PSN sequence and/or extinguish the optimalizations. If the function returns NULL, the type of the error can be figured out by using 'psnerrno' and the PE* values. */ char * psn_convert_symbolic(psn *seq,psnprop *plist,psnsymeval *syt, psnsym **sym,char *dformat); /* psn_argument_chain(): This function returns a dynamically allocated array which countains integers pointing to the operators or functions of which arguments are they. If something is wrong with 'seq', the function returns NULL and psnerrno is set appropriately. This function is useful to optimalize evaluation in some cases. E.g. when one wants to calculate A*B, and A is zero, therefore there is no need to calculate B. The returned array can be released by free(). */ int * psn_argument_chain(psn *seq); /* psn_free(): Releases the PSN sequence 'seq'. */ void psn_free(psn *seq); /* psn_register_function(): This function registers a new function (T_FN) with the given name 'name' to the symbol list, property list, function list, differential rule list and symbolic evaluation list (named 'syms', 'props', 'functs', 'diffs' and 'symevals', respectively). Note that these lists should be dynamically allocated lists (or NULLs). The new function has 'argnum' arguments, evaluated by the function 'funct', has a differential rule described by 'diffrule' and can be converted to human-readable string by 'symevalstr'. The latter two are optional, can be NULL, in this case 'diffs' and 'symevals' also can be NULL (and vice versa, if these are NULL, 'diffrule' and 'symevalstr' are ignored). */ int psn_register_function(psnsym **syms,psnprop **props, psnfunct **functs,psndiff **diffs,psnsymeval **symevals, int major,char *name,int argnum,int (*funct)(double *), short *diffrule,char *symevalstr); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/include/lfit/0000755000175000017500000000000011325431425013634 5ustar apalapalfitsh-0.9.2/include/lfit/lfit.h0000644000175000017500000000437411211473343014752 0ustar apalapal/*****************************************************************************/ /* lfit.h */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file should be included in all external (dynamically linked) library */ /* extensions designed for the `lfit` program. This file provides the object */ /* `lfitfunction` which shall be used to bind the external functions to the */ /* main `lfit` code. The modules must be compiled using the command */ /* gcc ... -fPIC -o module.so module.c ... -shared */ /* (with the additional compilation flags and object modules) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (c) 1996, 2002, 2004-2005, 2006, 2007-2008, 2009; */ /* Pal, Andras (apal@szofi.net) */ /*****************************************************************************/ #ifndef __LFIT_H_INCLUDED #define __LFIT_H_INCLUDED 1 /*****************************************************************************/ #define LFITFUNCTION_NONDIFFERENTIABLE 0x00 #define LFITFUNCTION_DIFFERENTIABLE 0x02 #define LFITFUNCTION_LINEAR 0x03 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ typedef struct { char *name; /* name of the given function */ int flags; /* see LFITFUNCTION_* above */ int nvar; /* number of adjustable variables */ int nidv; /* number of independent parameters */ int (*function) /* the callback function itself: */ (double *vars, /* - array of the adj. variables */ double *idvs, /* - array of the indep. param's */ double *ret, /* - return value */ double *diff); /* - partial derivatives */ } lfitfunction; /*****************************************************************************/ typedef struct { char *description; } psnfunctinfo; typedef struct { char *name; int type,major,minor; int argnum,precedency,associativity; int (*funct)(double *); short *diff; char *string; int strength,affixation; psnfunctinfo *info; } psnlfit; /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/CHANGELOG0000644000175000017500000001273212771631134012477 0ustar apalapal0.9.2: new features, changes and fixes since FITSH version 0.9.1 ================================================================ * fix: many parts related to "unused-but-set variables" are fixed. * new: a custom random generator library `librandom` has been added to the source tree: the standard libc functions (srand48(), drand48(), etc.) have been replaced by the calls provided by this `librandom` library. * fix: some minor fixes in the Makefile.in templates. * fix: Makefiles can safely be run in paralell now. This is due to a tiny hack (i.e. the make calls itself on the same directory) but works fine. * fix: some minor fixes in the ./deb/fitsh.control template. * new: the ./configure.mingw32 and ./configure.mingw64 script has been added and the configure.in emplate has been fixed in accordance with the requirements of the MINGW compilers. Hence, is it possible now to create MS Windows executables on systems where the MINGW compilers have been properly installed. Note that some FITSH features which are highly UNIX specific, won't work in these MS Windows environment or executables. * fix: ./Makefile.in: `make deb` target has been fixed (there isn't any /bin/bash specific commands) * fix: lazy evaluation bug in fitsmask.c:213 and :216 has been fixed. * obs: `grtfilter` and `grselect` has been removed from the source tree. The functionality intended to be providedby `grtfilter` can be implemented by `lfit`. The task `grselect` can be replaced by using `awk` or some similar basic text processing tool. * new: support for high dynamics (16-bit) PNM output is added to `fiinfo`. * new: support for --help-wiki output, which results a simple but elegant summary page about the available command line options using the Mediawiki markup language. The output can then be copied to any Mediawiki-based system (see also http://fitsh.net/wiki/). * new: support for simple polygon shaped apertures. See e.g. Fig 2. of http://arxiv.org/abs/1609.02760 for an application of such apertures. * obs: the support for various coordinate basis systems has been expunged from the full source. for backward compatibiliy, only the interpretation (and silent ignorance) of the "basissift" keyword is kept which is found in transformation files. The only coordinate basis is now the native one, in which the coordinate of the lower-left corner of the lower-left pixel is (0,0). This implies a shift w.r.t to the system used by IRAF where the center of the lower-left pixel is (1,1) since in IRAF system, the lower-left corner of the lower-left pixel is (0.5,0.5). * fix: parts of the code related to varios --help outputs have been fixed * fix: some common declarations and header files have been fixed * fix: minor fixes after testing at debian/stretch/gcc-6.1.1 * new: testing and minor fixes related to the support for CLANG and TinyCC * fix: some obsolete checks have been removed from ./configure * fix: the subdirectory ./src/parallel has been removed from the source tree * fix: internal debian package creation files have been moved to ./misc/deb * fix: some fixes in the `make install` and `make uninstall` targets * new: the directory ./man has been created with the man pages of the various tasks found in this package. This directory is shipped with the upstream package as well. 0.9.1: new features, changes and fixes since FITSH version 0.9.0 ================================================================ * fix: lfit/linear.so: -dylib argument is fixed on Mac/OSX targets. * new: fiphot: from now, a formally zero gain (--gain 0) imply an "infinite" gain, i.e. no photon noise from the detector. It can be conveniently used for photometry on images of instruments where photon noise is not an issue (e.g. Hersche/PACS images) or when photon noise is completely negligible (e.g. photometry of very faint targets). * new: fiarith: new per-image functions sign(.) and theta(.) are added. sign(.) is the standard sign function while theta(.) is the Heaviside step function (that is zero for negative numbers and unity for non-negative numbers). * fix: fiphot: some minor bug fixes related to the polynomial gain variation handling. * new: fitrans: simple image shift operations can be implied now using the -e or --shift command line options. * fix: lfit: the LIBC/math calls of finite(.) have been replaced to isfinite(.). * chg: The `fizip` and `fiunzip` tasks are removed from the whole package. We suggest to use the more sophisticated, faster and standard FITS compression tools `fpack` and `funpack`, that works nicely in parallel with the task of the FITSH package (not transparently, but standard input/output pipes can be built easily). As of now, a native support for the tile compression method used by `fpack` and `funpack` is not planned. * chg: Some standard project files (./AUTHORS, ./CHANGELOG, ./COPYING, ./INSTALL and ./README) have been added to the source tree. * new: The target `make deb` creates a Debian package on the current architecture (this feature requies the `dpkg-deb` utility and also depends on the `help2man` program in order to create the manual pages that also should go into the Debian package). * new: Related to the new `make deb` target, the subdirectory ./deb (currently with two files) has been created in the source tree. 0.9.0 ===== * new: The first public release of the FITSH package. See ./README and the inline reference manuals (--long-help) for further details. See also ./INSTALL for installation tips. fitsh-0.9.2/librandom/0000755000175000017500000000000012772016355013232 5ustar apalapalfitsh-0.9.2/librandom/random.c0000644000175000017500000000423711712470621014655 0ustar apalapal/*****************************************************************************/ /* random.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* (C) 2011; Pal, A. (apal@szofi.net); based on the code available in */ /* the book: Numerical Recipes: the art of scientific computing (3rd ed.) */ /*****************************************************************************/ #include #include #include #include static struct random_state state; static int is_initialized=0; #define R2P32 2.3283064365386962890625E-10 /*****************************************************************************/ int random_state_seed(struct random_state *state,int j) { state->v = 2244614371U; state->w1 = 521288629U; state->w2 = 362436069U; state->u = (uint32_t)j ^ state->v; random_state_uint32(state); state->v = state->u; random_state_uint32(state); return(0); } uint32_t random_state_uint32(struct random_state *state) { uint32_t x,y; state->u = state->u * 2891336453U + 1640531513U; state->v ^= state->v >> 13; state->v ^= state->v << 17; state->v ^= state->v >> 5; state->w1 = 33378 * (state->w1 & 0xffff) + (state->w1 >> 16); state->w2 = 57225 * (state->w2 & 0xffff) + (state->w2 >> 16); x = state->u ^ (state->u << 9); x ^= x >> 17; x ^= x << 6; y = state->w1 ^ (state->w1 << 17); y ^= y >> 15; y ^= y << 5; return((x+state->v)^(y+state->w2)); } double random_state_double(struct random_state *state) { uint32_t r1,r2; r1=random_state_uint32(state); r2=random_state_uint32(state); return(R2P32*((double)r1+R2P32*(double)r2)); } /*****************************************************************************/ int random_seed(int j) { random_state_seed(&state,j); is_initialized=1; return(0); } uint32_t random_uint32(void) { if ( ! is_initialized ) { random_seed(0); is_initialized=1; } return(random_state_uint32(&state)); } double random_double(void) { if ( ! is_initialized ) { random_seed(0); is_initialized=1; } return(random_state_double(&state)); } /*****************************************************************************/ fitsh-0.9.2/librandom/Makefile.in0000644000175000017500000000071011657730262015276 0ustar apalapalSHELL = /bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ CFLAGS=@CFLAGS@ DLEXT=@DLEXT@ DLSWC=@DLSWC@ INC=../include .PHONY: all clean all: librandom.a random.o: random.c $(INC)/random/random.h $(CC) $(CFLAGS) -I$(INC) -c random.c librandom.a: random.o $(AR) src librandom.a random.o $(RANLIB) librandom.a librandom.$(DLEXT): random.o $(LD) -o librandom.$(DLEXT) $(DLSWC) random.o chmod -x librandom.$(DLEXT) clean: rm -f *.o *.a *.$(DLEXT) fitsh-0.9.2/libfits/0000755000175000017500000000000012772016355012717 5ustar apalapalfitsh-0.9.2/libfits/fits-common.h0000644000175000017500000000470411236245643015326 0ustar apalapal/*****************************************************************************/ /* fits-common.h */ /*****************************************************************************/ #ifndef __FITS_COMMON_H_INCLUDED #define __FITS_COMMON_H_INCLUDED 1 #ifndef _FITS_SOURCE #error "This file (fits-common.h) is for internal usage, do not include directly." #endif #include #ifdef FITS_TAPE_BLOCKSIZE #undef FITS_TAPE_BLOCKSIZE #endif #define FITS_TAPE_BLOCKSIZE 2880 #ifdef FITS_TAPE_CARDIMAGESIZE #undef FITS_TAPE_CARDIMAGESIZE #endif #define FITS_TAPE_CARDIMAGESIZE 80 #define FITS_TAPE_CARDIMAGECOUNT 36 /*****************************************************************************/ #define BUFSIZE 16384 #define HDRBLOCKS 64 /*****************************************************************************/ #define HDR_NAXIS 0 #define HDR_NAXIS1 1 #define HDR_NAXIS2 2 #define HDR_NAXIS3 3 #define HDR_NAXIS4 4 #define HDR_BITPIX 5 #define HDR_BSCALE 6 #define HDR_BZERO 7 #define HDR_EXTEND 8 #define HDR_XTENSION 9 #define HDR_INHERIT 10 #define HDR_SIMPLE 11 #define HDR_ORIGIN 12 #define HDR_GAIN 13 #define HDR_END 14 #define HDR_TFIELDS 15 #define HDR_TBCOL 16 #define HDR_TFORM 17 #define HDR_TSCAL 18 #define HDR_TZERO 19 #define HDR_TNULL 20 #define HDR_TTYPE 21 #define HDR_TUNIT 22 #define HDR_PCOUNT 23 #define HDR_GCOUNT 24 extern char *headers[]; extern char *comment_fits_standard; extern int substantial_headers[]; /*****************************************************************************/ void * fits_tensor_alloc_arr(int typesize,int rank,int *arr); int fits_tensor_free(void *tensor); /*****************************************************************************/ int fits_arch_is_swapped(void); int fits_swap_line_bytes(unsigned char *wbuff,int bs,int sx); /*****************************************************************************/ int fits_cb_read (void *param,void *dst,int length); int fits_cb_write (void *param,void *src,int length); int fits_cb_skip (void *param,int length); int fits_cb_is_end(void *param); typedef struct { char *buffer; int length; } fitsmemwrite; int fits_cb_mem_write(void *param,void *src,int length); /*****************************************************************************/ #endif /*****************************************************************************/ fitsh-0.9.2/libfits/fits-table.c0000644000175000017500000002114011236245727015114 0ustar apalapal/*****************************************************************************/ /* fits-table.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* ASCII table extensions (XTENSION = 'TABLE') */ /* (c) 2006, Pal, A. (apal@szofi.elte.hu). */ /* See reference(s) at the end of this source code. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ int fits_table_get_params(fitsheaderset *header,fitsttable *ft) { fitsheader *hdr; fitstfield *tt; int i; char chdr[16]; memset(ft,0,sizeof(fitsttable)); hdr=fits_headerset_get_uniq_header(header,headers[HDR_NAXIS]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint != 2 ) return(1); hdr=fits_headerset_get_uniq_header(header,headers[HDR_BITPIX]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint != 8 ) return(1); hdr=fits_headerset_get_uniq_header(header,headers[HDR_NAXIS1]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint<=0 ) return(1); ft->rowsize=hdr->vint; hdr=fits_headerset_get_uniq_header(header,headers[HDR_NAXIS2]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint<=0 ) return(1); ft->nrow=hdr->vint; hdr=fits_headerset_get_uniq_header(header,headers[HDR_TFIELDS]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint<=0 ) return(1); ft->ntfield=hdr->vint; ft->tfields=(fitstfield *)malloc(sizeof(fitstfield)*ft->ntfield); for ( i=0 ; intfield ; i++ ) { tt=&ft->tfields[i]; sprintf(chdr,"%s%d",headers[HDR_TBCOL],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint<=0 ) { free(ft->tfields);return(1); } tt->colindex=hdr->vint-1; sprintf(chdr,"%s%d",headers[HDR_TFORM],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr==NULL || hdr->vtype != FITS_VSTR ) { free(ft->tfields);return(1); } strncpy(tt->format,hdr->vstr,11);tt->format[11]=0; tt->scale.bscale=1.0; tt->scale.bzero =0.0; tt->null[0]=0; tt->type[0]=0; tt->unit[0]=0; sprintf(chdr,"%s%d",headers[HDR_TSCAL],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL ) { if ( hdr->vtype==FITS_VINT ) tt->scale.bscale=hdr->vint; if ( hdr->vtype==FITS_VDOUBLE ) tt->scale.bscale=hdr->vdouble; } sprintf(chdr,"%s%d",headers[HDR_TZERO],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL ) { if ( hdr->vtype==FITS_VINT ) tt->scale.bzero=hdr->vint; if ( hdr->vtype==FITS_VDOUBLE ) tt->scale.bzero=hdr->vdouble; } sprintf(chdr,"%s%d",headers[HDR_TNULL],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL && hdr->vtype==FITS_VSTR ) { strncpy(tt->null,hdr->vstr,31);tt->null[31]=0; } sprintf(chdr,"%s%d",headers[HDR_TTYPE],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL && hdr->vtype==FITS_VSTR ) { strncpy(tt->type,hdr->vstr,31);tt->type[31]=0; } sprintf(chdr,"%s%d",headers[HDR_TUNIT],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL && hdr->vtype==FITS_VSTR ) { strncpy(tt->unit,hdr->vstr,31);tt->unit[31]=0; } } return(0); } int fits_table_alloc(fitsttable *ft) { int naxis[2]; naxis[0]=ft->rowsize; naxis[1]=ft->nrow; ft->allocdata=fits_tensor_alloc_arr(sizeof(unsigned char),2,naxis); ft->data=ft->allocdata; return(0); } int fits_table_read_cb(int (*cb_read)(void *,void *,int),void *param,fitsttable *ft) { int cread,i; cread=0; for ( i=0 ; inrow ; i++ ) { cb_read(param,ft->data[i],ft->rowsize); cread=(cread+ft->rowsize)%FITS_TAPE_BLOCKSIZE; } if ( cread>0 ) cb_read(param,NULL,FITS_TAPE_BLOCKSIZE-cread); return(0); } int fits_table_read(FILE *fr,fitsttable *ft) { return(fits_table_read_cb(fits_cb_read,(void *)fr,ft)); } int fits_table_skip_cb(int (*cb_read)(void *,void *,int),void *param,fitsttable *ft) { int bseek,btot; btot=ft->rowsize*ft->nrow; if ( btot<=0 ) return(1); bseek=(btot+FITS_TAPE_BLOCKSIZE-1)/FITS_TAPE_BLOCKSIZE; cb_read(param,NULL,bseek*FITS_TAPE_BLOCKSIZE); return(0); } int fits_table_skip(FILE *fr,fitsttable *ft) { return(fits_table_skip_cb(fits_cb_read,(void *)fr,ft)); } /*****************************************************************************/ int fits_table_set_params(fitsheaderset *header,fitsttable *ft) { int ret,i; char chdr[16]; fitstfield *tt; if ( ft==NULL ) return(1); ret=0; ret|=fits_headerset_set_string(header,headers[HDR_XTENSION],FITS_SH_FIRST,"TABLE",NULL); ret|=fits_headerset_set_integer(header,headers[HDR_BITPIX],FITS_SH_FIRST,8,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_NAXIS],FITS_SH_FIRST,2,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_NAXIS1],FITS_SH_FIRST,ft->rowsize,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_NAXIS2],FITS_SH_FIRST,ft->nrow,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_PCOUNT],FITS_SH_FIRST,0,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_GCOUNT],FITS_SH_FIRST,1,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_TFIELDS],FITS_SH_FIRST,ft->ntfield,NULL); for ( i=0 ; intfield && ft->tfields != NULL ; i++ ) { tt=&ft->tfields[i]; sprintf(chdr,"%s%d",headers[HDR_TBCOL],i+1); ret|=fits_headerset_set_integer(header,chdr,FITS_SH_FIRST,tt->colindex+1,NULL); sprintf(chdr,"%s%d",headers[HDR_TFORM],i+1); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,tt->format,NULL); if ( tt->null[0] ) { sprintf(chdr,"%s%d",headers[HDR_TNULL],i+1); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,tt->null,NULL); } if ( tt->type[0] ) { sprintf(chdr,"%s%d",headers[HDR_TTYPE],i+1); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,tt->type,NULL); } if ( tt->unit[0] ) { sprintf(chdr,"%s%d",headers[HDR_TUNIT],i+1); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,tt->unit,NULL); } if ( tt->scale.bscale != 1.0 || tt->scale.bzero != 0.0 ) { sprintf(chdr,"%s%d",headers[HDR_TSCAL],i+1); ret|=fits_headerset_set_double(header,chdr,FITS_SH_FIRST,tt->scale.bscale,NULL); sprintf(chdr,"%s%d",headers[HDR_TZERO],i+1); ret|=fits_headerset_set_double(header,chdr,FITS_SH_FIRST,tt->scale.bzero ,NULL); } } return(ret); } /*****************************************************************************/ int fits_table_write_cb(int (*cb_write)(void *,void *,int),void *param,fitsttable *ft,int is_pad) { int wr; int i,psize; char *padding; if ( ft==NULL || ft->data==NULL ) return(0); wr=0; for ( i=0 ; inrow ; i++ ) { cb_write(param,ft->data[i],ft->rowsize); wr+=ft->rowsize; } if ( is_pad && wr%FITS_TAPE_BLOCKSIZE>0 ) { psize=FITS_TAPE_BLOCKSIZE-(wr%FITS_TAPE_BLOCKSIZE); padding=(char *)malloc(psize); memset(padding,32,psize); cb_write(param,padding,psize); wr+=psize; free(padding); } return(wr); } int fits_table_write(FILE *fw,fitsttable *ft,int is_pad) { return(fits_table_write_cb(fits_cb_write,(void *)fw,ft,is_pad)); } /*****************************************************************************/ int fits_table_free(fitsttable *ft) { if ( ft->allocdata != NULL ) fits_tensor_free(ft->allocdata); ft->allocdata=NULL; ft->data=NULL; if ( ft->tfields != NULL && ft->ntfield>0 ) free(ft->tfields); ft->ntfield=0; ft->tfields=NULL; ft->nrow=0; ft->rowsize=0; return(0); } int fits_table_duplicate(fitsttable *dt,fitsttable *st,int flag) { int naxis[2]; dt->nrow=st->nrow; dt->rowsize=st->rowsize; dt->ntfield=st->ntfield; dt->tfields=(fitstfield *)malloc(sizeof(fitstfield)*dt->ntfield); memcpy(dt->tfields,st->tfields,sizeof(fitstfield)*dt->ntfield); naxis[0]=dt->rowsize; naxis[1]=dt->nrow; if ( dt->data != NULL ) { dt->data=fits_tensor_alloc_arr(1,2,naxis); memcpy(&dt->data[0][0],&st->data[0][0],dt->rowsize*dt->nrow); dt->allocdata=dt->data; } else { dt->data=NULL; dt->allocdata=NULL; } return(0); } /****************************************************************************** Reference: [1]: Definition of the Flexible Image Transport System (FITS) NASA / Science Office of Standards and Technology (NOST) NOST 100-2.0 (March 29, 1999) NASA Goddard Space Flight Center http://fits.gsfc.nasa.gov/fits_documentation.html ******************************************************************************/ fitsh-0.9.2/libfits/fits-ui.c0000644000175000017500000001113412766533654014454 0ustar apalapal/*****************************************************************************/ /* fits.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* Some functions for nice user-interfaces... */ /* (c) 2004-06, Pal, A. (apal@szofi.elte.hu). */ /* See reference(s) at the end of this source code. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ static char *local_basename=NULL; char * fits_basename(char *name,int *rframeno) { int frameno,len,pos,cnt; char *rname; if ( name==NULL ) { if ( rframeno != NULL ) *rframeno=-1; return(NULL); } len=strlen(name); if ( local_basename==NULL ) { local_basename=strdup(name); } else { if ( strlen(local_basename)0 && pos>0 ) ) pos=0; } else pos=0; if ( pos>0 ) { sscanf(rname+pos+1,"%d",&frameno); if ( frameno<=0 ) frameno=-1,rname=name; else frameno--,rname[pos]=0; } else frameno=-1,rname=name; if ( rframeno != NULL ) *rframeno=frameno; return(rname); } /*****************************************************************************/ static char fits_nasty_chars[]="()*?[]&|;{}#'"; static int fits_is_nasty_char(int t) { if ( strchr(fits_nasty_chars,t)==NULL ) return(0); else return(1); } static int fits_is_any_nasty_char(char *buff) { for ( ; *buff ; buff++ ) { if ( fits_is_nasty_char(*buff) ) return(1); } return(0); } int fits_header_export_command_line(fits *img, char *hdr,char *first,char *prefix,int argc,char *argv[]) { char *buff,wbuff[80]; int i,tk,l,p,mxl,plen; if ( prefix==NULL ) { mxl=65; plen=0; } else { plen=strlen(prefix); if ( plen>32 ) plen=32; mxl=65-plen; } if ( first != NULL ) fits_headerset_set_string(&img->header,hdr,FITS_SH_ADD,first,NULL); buff=NULL;p=0; for ( i=0 ; imxl ) i=mxl; if ( prefix != NULL ) { strncpy(wbuff,prefix,plen); memcpy(wbuff+plen,buff+l,i); wbuff[plen+i]=0; } else { memcpy(wbuff,buff+l,i); wbuff[i]=0; } if ( p-l>mxl ) strcat(wbuff,"\\"); fits_headerset_set_string(&img->header,hdr,FITS_SH_ADD,wbuff,NULL); l+=i; } if ( buff != NULL ) free(buff); return(0); } /*****************************************************************************/ typedef struct { int code; char *message; } errmsg; errmsg fits_error_messages[]= { { FITSERR_OPEN , "unable to open input file" }, { FITSERR_ALLOC , "unsuccessful memory allocation" }, { FITSERR_FRAME_MISSING, "missing frame number specification" }, { FITSERR_FRAME_AMBIG , "ambigous frame number" }, { FITSERR_FRAME_INVALID, "invalid frame number" }, { FITSERR_IMAGE , "unable to treat input as a FITS image" }, { FITSERR_SCALE , "unable to rescale inpt image" }, { -1,NULL } }; char *fits_error(int errcode) { errmsg *e; for ( e=fits_error_messages ; e->code>=0 && e->message != NULL ; e++ ) { if ( e->code == errcode ) return(e->message); } return(NULL); } /*****************************************************************************/ FILE * fits_file_open(char *name) { FILE *fr; if ( name==NULL ) fr=NULL; else if ( strcmp(name,"-")==0 ) fr=stdin; else fr=fopen(name,"rb"); return(fr); } FILE * fits_file_create(char *name) { FILE *fw; if ( name==NULL ) fw=NULL; else if ( strcmp(name,"-")==0 ) fw=stdout; else fw=fopen(name,"wb"); return(fw); } int fits_file_close(FILE *f) { int ret; if ( fileno(f) != fileno(stdin) && fileno(f) != fileno(stdout) ) ret=fclose(f); else ret=0; return(ret); } /*****************************************************************************/ fitsh-0.9.2/libfits/fits-image.c0000644000175000017500000004472411315631646015121 0ustar apalapal/*****************************************************************************/ /* fits-image.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* Image extensions (XTENSION = 'IMAGE') and primary images. */ /* (c) 2004-06, Pal, A. (apal@szofi.elte.hu). */ /* See reference(s) at the end of this source code. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ int fits_image_alloc(fitsimage *fi,int sx,int sy) { double **r; int arr[2]; arr[0]=sx,arr[1]=sy; r=(double **)fits_tensor_alloc_arr(sizeof(double),2,arr); fi->dim=2; fi->naxis[0]=sx; fi->naxis[1]=sy; fi->sx=sx, fi->sy=sy; fi->data=r; fi->allocdata=fi->vdata=(void *)r; return(0); } double ** fits_image_first_layer(void *data,int dim) { while ( dim>2 ) { data=*(void **)data; dim--; }; return((double **)data); } double * fits_image_first_pixel(void *data,int dim) { while ( dim>1 ) { data=*(void **)data; dim--; }; return((double *)data); } int fits_image_total_pixels(int dim,int *naxis) { int ntot; ntot=1; while ( dim>0 ) { if ( *naxis <= 0 ) return(-1); ntot=ntot*(*naxis); dim--,naxis++; }; return(ntot); } int fits_image_alloc_gen(fitsimage *fi,int dim,int *pnaxis) { void *vdata; int i,*naxis,cnaxis[2]; if ( dim<1 || dim>FITS_MAX_NAXIS ) return(1); else if ( dim==1 ) { cnaxis[0]=pnaxis[0]; cnaxis[1]=1; dim=2; naxis=cnaxis; } else naxis=pnaxis; vdata=fits_tensor_alloc_arr(sizeof(double),dim,naxis); if ( vdata==NULL ) return(-1); fi->dim=dim; for ( i=0 ; inaxis[i]=naxis[i]; fi->data=fits_image_first_layer(vdata,dim); fi->allocdata=vdata; fi->vdata=vdata; fi->sx=naxis[0]; fi->sy=naxis[1]; return(0); } int fits_image_alloc_2d(fitsimage *fi,int sx,int sy) { return ( fits_image_alloc(fi,sx,sy) ); } int fits_image_alloc_3d(fitsimage *fi,int sx,int sy,int sz) { int pnaxis[3]; pnaxis[0]=sx, pnaxis[1]=sy, pnaxis[2]=sz; return ( fits_image_alloc_gen(fi,3,pnaxis) ); } /*****************************************************************************/ void fits_image_free(fitsimage *fi) { if ( fi->allocdata != NULL ) fits_tensor_free(fi->allocdata); fi->allocdata=fi->vdata=NULL; fi->data=NULL; fi->sx=0,fi->sy=0; fi->dim=0; } /*****************************************************************************/ int fits_image_set_value(fitsimage *fi,double value) { int i,ntot; double *ddata; if ( fi==NULL || fi->vdata==NULL ) return(1); ddata=fits_image_first_pixel (fi->vdata,fi->dim); ntot =fits_image_total_pixels(fi->dim,fi->naxis); for ( i=0 ; ivtype==FITS_VINT ) bscale=(double)hdr->vint; /* Integer */ else if ( hdr->vtype==FITS_VDOUBLE ) bscale=(double)hdr->vdouble; /* Double */ else return(1); /* Everything else, ignored */ hdr=fits_headerset_get_header(header,headers[HDR_BZERO],0); if ( hdr==NULL ) bzero=0.0; /* Default BZERO is 0 */ else if ( hdr->vtype==FITS_VINT ) bzero=(double)hdr->vint; else if ( hdr->vtype==FITS_VDOUBLE ) bzero=(double)hdr->vdouble; else return(1); if ( rbscale != NULL ) *rbscale=bscale; if ( rbzero != NULL ) *rbzero =bzero; return(0); } int fits_image_get_params(fitsheaderset *header,fitsimage *fi) { int sx,sy,bit,naxis[FITS_MAX_NAXIS],dim,i; fitsheader *hdr; char naxishdr[16]; hdr=fits_headerset_get_uniq_header(header,headers[HDR_NAXIS]); if ( hdr==NULL || hdr->vtype != FITS_VINT ) return(1); dim=hdr->vint; if ( dim<1 || dim>FITS_MAX_NAXIS ) return(1); for ( i=0 ; ivtype != FITS_VINT ) return(1); naxis[i]=hdr->vint; } sx=naxis[0]; if ( dim==1 ) sy=1; else sy=naxis[1]; hdr=fits_headerset_get_uniq_header(header,headers[HDR_BITPIX]); if ( hdr==NULL || hdr->vtype != FITS_VINT ) return(1); bit=hdr->vint; fi->dim=dim; for ( i=0 ; inaxis[i]=naxis[i]; } fi->sx=sx, fi->sy=sy, fi->bit=bit; fits_image_get_scale(header,fi,&fi->read.bscale,&fi->read.bzero); fi->curr.bscale=fi->read.bscale; fi->curr.bzero =fi->read.bzero; return(0); } /*****************************************************************************/ int fits_image_rescale(fitsimage *fi) { int i,ntot; double bscale,bzero,*ddata; if ( fi==NULL || fi->vdata==NULL ) return(0); if ( fi->sx==0 || fi->sy==0 ) return(0); bscale=fi->curr.bscale; bzero =fi->curr.bzero; if ( bscale==1.0 && bzero==0.0 ) return(0); /* Identity... */ ddata=fits_image_first_pixel(fi->vdata,fi->dim); ntot=fits_image_total_pixels(fi->dim,fi->naxis); for ( i=0 ; icurr.bscale=1.0; fi->curr.bzero =0.0; return(0); } int fits_image_backscale(fitsimage *fi,double ibscale,double ibzero) { int i,ntot; double bscale,bzero,*ddata; if ( fi==NULL || fi->vdata==NULL ) return(0); if ( fi->sx==0 || fi->sy==0 ) return(0); if ( ibscale==0.0 ) return(1); /* invalid scale */ bscale=fi->curr.bscale; bzero =fi->curr.bzero; if ( bscale==1.0 && bzero==0.0 && ibscale==1.0 && ibzero==0.0 ) return(0); ddata=fits_image_first_pixel(fi->vdata,fi->dim); ntot=fits_image_total_pixels(fi->dim,fi->naxis); if ( bscale != 1.0 || bzero != 0.0 ) { for ( i=0 ; icurr.bscale=ibscale; fi->curr.bzero =ibzero; return(0); } /*****************************************************************************/ int fits_image_quantize(fitsimage *fi,int nquantizebit) { int i,ntot; double *ddata,x,bm,mm; long l,m; if ( fi==NULL || fi->vdata==NULL ) return(0); if ( fi->sx==0 || fi->sy==0 ) return(0); if ( nquantizebit>=sizeof(long double)*8 ) return(0); ddata=fits_image_first_pixel(fi->vdata,fi->dim); ntot=fits_image_total_pixels(fi->dim,fi->naxis); if ( nquantizebit==0 ) { for ( i=0 ; ibit,NULL); k|=fits_headerset_set_integer(header,headers[HDR_NAXIS],FITS_SH_FIRST,fi->dim,NULL); for ( i=0 ; idim ; i++ ) { sprintf(naxishdr,"%s%d",headers[HDR_NAXIS],i+1); k|=fits_headerset_set_integer(header,naxishdr,FITS_SH_FIRST,fi->naxis[i],NULL); } for ( i=fi->dim ; i<=999 ; i++ ) { sprintf(naxishdr,"%s%d",headers[HDR_NAXIS],i+1); if ( ! fits_headerset_get_count(header,naxishdr) ) break; else fits_headerset_delete_all(header,naxishdr); } nn=fits_headerset_get_id(header,headers[HDR_NAXIS],0); if ( nn>=0 ) nn++; for ( i=0 ; idim && nn>=0 ; i++ ) { sprintf(naxishdr,"%s%d",headers[HDR_NAXIS],i+1); nc=fits_headerset_get_id(header,naxishdr,0); /* fprintf(stderr,"nn=%d nc=%d\n",nn,nc); */ if ( nc>nn ) { fitsheader th; th=header->hdrs[nc]; memmove(header->hdrs+nn+1,header->hdrs+nn,sizeof(fitsheader)*(nc-nn)); header->hdrs[nn]=th; nn++; } else if ( nc==nn ) nn++; } k|=fits_headerset_set_double (header,headers[HDR_BSCALE],FITS_SH_FIRST,fi->read.bscale,NULL); k|=fits_headerset_set_double (header,headers[HDR_BZERO],FITS_SH_FIRST ,fi->read.bzero,NULL); return(k); } /*****************************************************************************/ int fits_image_read_cb(int (*cb_read)(void *,void *,int),void *param,fitsimage *fi) { int i,cread,ntot,nline,sx; double *ddata; ddata=fits_image_first_pixel(fi->vdata,fi->dim); ntot=fits_image_total_pixels(fi->dim,fi->naxis); sx=fi->naxis[0]; nline=ntot/sx; for ( i=0,cread=0 ; ibit,ddata+i*sx))%2880; if ( cread>0 ) cb_read(param,NULL,2880-cread); return(0); } int fits_image_read(FILE *fr,fitsimage *fi) { return(fits_image_read_cb(fits_cb_read,(void *)fr,fi)); } int fits_image_skip_cb(int (*cb_read)(void *,void *,int),void *param,fitsimage *fi) { int ntot,bs,btot,bseek; bs=fi->bit; if ( bs<0 ) bs=-bs; bs=bs/8; if ( bs<=0 ) return(1); ntot=fits_image_total_pixels(fi->dim,fi->naxis); if ( ntot<=0 ) return(1); btot=ntot*bs; bseek=(btot+FITS_TAPE_BLOCKSIZE-1)/FITS_TAPE_BLOCKSIZE; cb_read(param,NULL,bseek*FITS_TAPE_BLOCKSIZE); return(0); } int fits_image_skip(FILE *fr,fitsimage *fi) { return(fits_image_skip_cb(fits_cb_read,(void *)fr,fi)); } /*****************************************************************************/ int fits_image_write_line_cb(int (*cb_write)(void *,void *,int),void *param,int sx,int bit,double *line) { int j,bs; unsigned char *wbuff,*w; bs=bit; if ( bs<0 ) bs=-bs; bs=bs/8; wbuff=(unsigned char *)malloc((unsigned)(sx*bs)); if ( wbuff==NULL ) return(0); /* Allocation error, nothing written... */ switch ( bit ) { case 8: for ( j=0,w=wbuff ; jvdata,fi->dim); ntot=fits_image_total_pixels(fi->dim,fi->naxis); sx=fi->naxis[0]; nline=ntot/sx; wr=0; for ( i=0 ; ibit,ddata+i*sx); } if ( is_pad && wr%FITS_TAPE_BLOCKSIZE ) { psize=FITS_TAPE_BLOCKSIZE-(wr%FITS_TAPE_BLOCKSIZE); padding=(char *)malloc(psize); memset(padding,0,psize); cb_write(param,padding,psize); wr+=psize; free(padding); } return(wr); /* total bytes written */ } int fits_image_write(FILE *fw,fitsimage *fi,int is_pad) { return(fits_image_write_cb(fits_cb_write,(void *)fw,fi,is_pad)); } /*****************************************************************************/ double * fits_image_dump(fitsimage *fi) { int ntot; double *ddata,*raw; if ( fi==NULL || fi->vdata==NULL ) return(NULL); ddata=fits_image_first_pixel(fi->vdata,fi->dim); ntot=fits_image_total_pixels(fi->dim,fi->naxis); raw=(double *)malloc(sizeof(double)*ntot); if ( raw==NULL ) return(NULL); memcpy(raw,ddata,sizeof(double)*ntot); return(raw); } /*****************************************************************************/ int fits_image_duplicate(fitsimage *ret,fitsimage *img,int flag) { double *idata,*rdata; int ntot; if ( img->vdata != NULL ) { ret->bit=img->bit; memcpy(&ret->read,&img->read,sizeof(fitsscale)); memcpy(&ret->curr,&img->curr,sizeof(fitsscale)); /* this also sets ret->sx, ret->sy and ret->data properly */ fits_image_alloc_gen(ret,img->dim,img->naxis); ntot=fits_image_total_pixels(img->dim,img->naxis); idata=fits_image_first_pixel(img->vdata,img->dim); rdata=fits_image_first_pixel(ret->vdata,ret->dim); if ( flag ) memcpy(rdata,idata,sizeof(double)*ntot); else memset(rdata,0,sizeof(double)*ntot); } else { ret->sx=ret->sy=0; ret->bit=0; ret->data=NULL; ret->dim=0; ret->vdata=NULL; ret->allocdata=NULL; ret->read.bscale=1.0,ret->read.bzero=0.0; ret->curr.bscale=1.0,ret->curr.bzero=0.0; } return(0); } /*****************************************************************************/ char * fits_image_bitpix_cname(int bitpix) { char *ret; switch ( bitpix ) { case 8: ret="byte"; break; case 16: ret="short"; break; case 32: ret="long"; break; case -32: ret="float"; break; case -64: ret="double";break; default : ret=NULL;break; } return(ret); } /*****************************************************************************/ static int fits_image_expand(double ***rdata,int sx,int sy,int nx,int ny,double fill) { double **data; size_t ns; int i,j; if ( nx=0 ; i-- ) { memmove(((double *)(data+ny))+i*nx,((double *)(data+sy))+i*sx,sx*sizeof(double)); for ( j=sx ; jsx || ny>sy ) return(-1); else if ( nx==sx && ny==sy ) return(0); data=*rdata; for ( i=0 ; i=ty ) { for ( j=0 ; j0 ) { if ( x0<0 ) { c=-x0; if ( c>l ) c=l; for ( j=0 ; j=tx ) { c=l; for ( j=0 ; jl ) c=l; for ( j=0 ; jallocdata != (void *)img->data || img->vdata != (void *)img->data || img->data==NULL ) return(-2); else if ( img->dim != 2 ) return(-2); sx=img->sx; sy=img->sy; if ( sx<=0 || sy<=0 ) return(-2); tx=(nx>sx?nx:sx); ty=(ny>sy?ny:sy); fits_image_expand(&img->data,sx,sy,tx,ty,outer); line=(double *)malloc(tx*sizeof(double)); if ( x0 != 0 || y0 != 0 ) { if ( y0>0 ) { for ( i=0 ; idata,tx,ty,x0,i+y0,line,outer); memcpy(img->data[i],line,tx*sizeof(double)); } } else { for ( i=ty-1 ; i>=0 ; i-- ) { fits_image_copy_line(img->data,tx,ty,x0,i+y0,line,outer); memcpy(img->data[i],line,tx*sizeof(double)); } } } free(line); fits_image_shrink(&img->data,tx,ty,nx,ny); img->sx=nx; img->sy=ny; img->naxis[0]=nx; img->naxis[1]=ny; img->vdata=img->allocdata=(void *)img->data; return(0); } /****************************************************************************** Reference: [1]: Definition of the Flexible Image Transport System (FITS) NASA / Science Office of Standards and Technology (NOST) NOST 100-2.0 (March 29, 1999) NASA Goddard Space Flight Center http://fits.gsfc.nasa.gov/fits_documentation.html ******************************************************************************/ fitsh-0.9.2/libfits/fits-bintable.c0000644000175000017500000003472012766533627015625 0ustar apalapal/*****************************************************************************/ /* fits-bintable.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* Binary table extensions (XTENSION = 'BINTABLE') */ /* (c) 2006, Pal, A. (apal@szofi.elte.hu). */ /* See reference(s) at the end of this source code. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ int fits_bintable_form_basesize(int form) { int basesize; switch ( form ) /* basesize = 0 means: basesize is a bit, 1/8 byte */ { case FTF_LOGICAL : basesize= 1;break; case FTF_BIT : basesize= 0;break; case FTF_BYTE : basesize= 1;break; case FTF_SHORT : basesize= 2;break; case FTF_LONG : basesize= 4;break; case FTF_LONGLONG : basesize= 8;break; case FTF_CHAR : basesize= 1;break; case FTF_FLOAT : basesize= 4;break; case FTF_DOUBLE : basesize= 8;break; case FTF_FLOATCOMPLEX : basesize= 8;break; case FTF_DOUBLECOMPLEX : basesize=16;break; case FTF_ARRAY : basesize= 8;break; default : basesize=-1;break; } return(basesize); } char *fits_bintable_form_cname(int form) { char *ret; switch ( form ) { case FTF_LOGICAL : ret="logical"; break; case FTF_BIT : ret="bit"; break; case FTF_BYTE : ret="byte"; break; case FTF_SHORT : ret="short"; break; case FTF_LONG : ret="long"; break; case FTF_LONGLONG : ret="long long"; break; case FTF_CHAR : ret="char*"; break; case FTF_FLOAT : ret="float"; break; case FTF_DOUBLE : ret="double"; break; case FTF_FLOATCOMPLEX : ret="float complex"; break; case FTF_DOUBLECOMPLEX : ret="double complex"; break; case FTF_ARRAY : ret="array"; break; default : ret=NULL; break; } return(ret); } /*****************************************************************************/ int fits_bintable_get_params(fitsheaderset *header,fitsbtable *fb) { fitsheader *hdr; fitsbfield *tb; int i,repeat,form,basesize,offset; char chdr[16],c; memset(fb,0,sizeof(fitsbtable)); hdr=fits_headerset_get_uniq_header(header,headers[HDR_NAXIS]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint != 2 ) return(1); hdr=fits_headerset_get_uniq_header(header,headers[HDR_BITPIX]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint != 8 ) return(1); hdr=fits_headerset_get_uniq_header(header,headers[HDR_NAXIS1]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint<=0 ) return(1); fb->rowsize=hdr->vint; hdr=fits_headerset_get_uniq_header(header,headers[HDR_NAXIS2]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint<=0 ) return(1); fb->nrow=hdr->vint; hdr=fits_headerset_get_uniq_header(header,headers[HDR_TFIELDS]); if ( hdr==NULL || hdr->vtype != FITS_VINT || hdr->vint<=0 ) return(1); fb->nbfield=hdr->vint; fb->bfields=(fitsbfield *)malloc(sizeof(fitsbfield)*fb->nbfield); offset=0; for ( i=0 ; inbfield ; i++ ) { tb=&fb->bfields[i]; sprintf(chdr,"%s%d",headers[HDR_TFORM],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr==NULL || hdr->vtype != FITS_VSTR ) { free(fb->bfields);return(1); } if ( isdigit((int)hdr->vstr[0]) ) { if ( sscanf(hdr->vstr,"%d%c",&repeat,&c)<2 ) { free(fb->bfields);return(1); } } else { c=toupper((int)hdr->vstr[0]); repeat=1; } form=(int)c; basesize=fits_bintable_form_basesize(form); if ( basesize<0 ) { free(fb->bfields);return(1); } tb->form=form; tb->basesize=basesize; tb->repeat=repeat; tb->offset=offset; if ( basesize>0 ) offset+=basesize*repeat; else offset+=(repeat+7)/8; tb->scale.bscale=1.0; tb->scale.bzero =0.0; tb->null[0]=0; tb->type[0]=0; tb->unit[0]=0; sprintf(chdr,"%s%d",headers[HDR_TSCAL],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL ) { if ( hdr->vtype==FITS_VINT ) tb->scale.bscale=hdr->vint; if ( hdr->vtype==FITS_VDOUBLE ) tb->scale.bscale=hdr->vdouble; } sprintf(chdr,"%s%d",headers[HDR_TZERO],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL ) { if ( hdr->vtype==FITS_VINT ) tb->scale.bzero=hdr->vint; if ( hdr->vtype==FITS_VDOUBLE ) tb->scale.bzero=hdr->vdouble; } sprintf(chdr,"%s%d",headers[HDR_TNULL],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL && hdr->vtype==FITS_VSTR ) { strncpy(tb->null,hdr->vstr,31);tb->null[31]=0; } sprintf(chdr,"%s%d",headers[HDR_TTYPE],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL && hdr->vtype==FITS_VSTR ) { strncpy(tb->type,hdr->vstr,31);tb->type[31]=0; } sprintf(chdr,"%s%d",headers[HDR_TUNIT],i+1); hdr=fits_headerset_get_uniq_header(header,chdr); if ( hdr != NULL && hdr->vtype==FITS_VSTR ) { strncpy(tb->unit,hdr->vstr,31);tb->unit[31]=0; } } return(0); } int fits_bintable_create_fields(fitsbtable *fb,int nrow,int nbfield,...) { va_list ap; int i,repeat,form,basesize,offset; /* check whether the field descriptor array is initialized or not: */ if ( fb->bfields != NULL || fb->nbfield != 0 ) return(1); if ( nbfield<=0 ) return(0); va_start(ap,nbfield); fb->bfields=(fitsbfield *)malloc(sizeof(fitsbfield)*nbfield); fb->nbfield=nbfield; offset=0; for ( i=0 ; i=0 ; i++ ) { form=va_arg(ap,int); repeat=va_arg(ap,int); basesize=fits_bintable_form_basesize(form); if ( basesize<0 || repeat<=0 ) { offset=-1;break; } fb->bfields[i].form=form; fb->bfields[i].repeat=repeat; fb->bfields[i].basesize=basesize; fb->bfields[i].offset=offset; fb->bfields[i].scale.bscale=1.0; fb->bfields[i].scale.bzero =0.0; fb->bfields[i].null[0]=0; fb->bfields[i].type[0]=0; fb->bfields[i].unit[0]=0; if ( basesize>0 ) offset+=basesize*repeat; else offset+=(repeat+7)/8; } if ( offset<0 ) free(fb->bfields); va_end(ap); fb->rowsize=offset; fb->nrow=nrow; if ( offset<0 ) return(1); else return(0); } int fits_bintable_check_fields(fitsbtable *fb,int nbfield,...) { va_list ap; int i,repeat,form,basesize; if ( fb->nbfield != nbfield ) return(1); if ( fb->bfields == NULL ) return(1); va_start(ap,nbfield); for ( i=0 ; ibfields[i].form != form ) return(1); if ( fb->bfields[i].repeat != repeat ) return(1); } return(0); } int fits_bintable_set_xtr_params(fitsbtable *fb,int n,char *type,char *unit,char *null) { fitsbfield *bb; if ( n<0 || n>=fb->nbfield ) return(1); if ( fb->bfields==NULL ) return(1); bb=&fb->bfields[n]; if ( type != NULL ) { strncpy(bb->type,type,31);bb->type[31]=0; } if ( unit != NULL ) { strncpy(bb->unit,unit,31);bb->unit[31]=0; } if ( null != NULL ) { strncpy(bb->null,null,31);bb->null[31]=0; } return(0); } int fits_bintable_set_xtr_scale(fitsbtable *fb,int n,double bscale,double bzero) { fitsbfield *bb; if ( n<0 || n>=fb->nbfield ) return(1); if ( fb->bfields==NULL ) return(1); bb=&fb->bfields[n]; bb->scale.bscale=bscale; bb->scale.bzero =bzero ; return(0); } int fits_bintable_alloc(fitsbtable *fb) { int naxis[2]; naxis[0]=fb->rowsize; naxis[1]=fb->nrow; fb->allocdata=fits_tensor_alloc_arr(sizeof(unsigned char),2,naxis); fb->data=fb->allocdata; return(0); } int fits_bintable_swap_line(unsigned char *data,int rowsize,fitsbfield *bfs,int nbf) { int i,n,basesize; unsigned char w; for ( i=0 ; i1 ) { while ( n>0 ) { switch ( basesize ) { case 2: w=data[0],data[0]=data[1],data[1]=w; break; case 4: w=data[0],data[0]=data[3],data[3]=w; w=data[1],data[1]=data[2],data[2]=w; break; case 8: w=data[0],data[0]=data[7],data[7]=w; w=data[1],data[1]=data[6],data[6]=w; w=data[2],data[2]=data[5],data[5]=w; w=data[3],data[3]=data[4],data[4]=w; break; } data+=basesize; n--; } } else { data+=basesize*n; } } return(0); } int fits_bintable_read_line_cb(int (*cb_read)(void *,void *,int),void *param,unsigned char *data,int rowsize,fitsbfield *bfs,int nbf) { cb_read(param,data,rowsize); if ( bfs==NULL || nbf<0 ) return(0); if ( ! fits_arch_is_swapped() ) { return(0); } else { fits_bintable_swap_line(data,rowsize,bfs,nbf); return(0); } } int fits_bintable_read_cb(int (*cb_read)(void *,void *,int),void *param,fitsbtable *fb) { int cread,i; cread=0; for ( i=0 ; inrow ; i++ ) { fits_bintable_read_line_cb(cb_read,param,fb->data[i],fb->rowsize,fb->bfields,fb->nbfield); cread=(cread+fb->rowsize)%FITS_TAPE_BLOCKSIZE; } if ( cread>0 ) cb_read(param,NULL,FITS_TAPE_BLOCKSIZE-cread); return(0); } int fits_bintable_read(FILE *fr,fitsbtable *fb) { return(fits_bintable_read_cb(fits_cb_read,(void *)fr,fb)); } int fits_bintable_skip_cb(int (*cb_read)(void *,void *,int),void *param,fitsbtable *fb) { int bseek,btot; btot=fb->rowsize*fb->nrow; if ( btot<=0 ) return(1); bseek=(btot+FITS_TAPE_BLOCKSIZE-1)/FITS_TAPE_BLOCKSIZE; cb_read(param,NULL,bseek*FITS_TAPE_BLOCKSIZE); return(0); } int fits_bintable_skip(FILE *fr,fitsbtable *fb) { return(fits_bintable_skip_cb(fits_cb_read,(void *)fr,fb)); } /*****************************************************************************/ int fits_bintable_set_offsets(fitsbtable *fb) { int i,offset,basesize; fitsbfield *tb; offset=0; for ( i=0 ; inbfield && fb->bfields != NULL ; i++ ) { tb=&fb->bfields[i]; basesize=fits_bintable_form_basesize(tb->form); if ( basesize<0 ) return(-1); tb->basesize=basesize; tb->offset=offset; if ( basesize>0 ) offset+=basesize*tb->repeat; else offset+=(tb->repeat+7)/8; } if ( offset != fb->rowsize ) { fb->rowsize=offset; return(1); } else return(0); } int fits_bintable_set_params(fitsheaderset *header,fitsbtable *fb) { int ret,i; char chdr[16],cfrm[16]; fitsbfield *tb; if ( fb==NULL ) return(1); ret=0; fits_bintable_set_offsets(fb); ret|=fits_headerset_set_string(header,headers[HDR_XTENSION],FITS_SH_FIRST,"BINTABLE",NULL); ret|=fits_headerset_set_integer(header,headers[HDR_BITPIX],FITS_SH_FIRST,8,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_NAXIS],FITS_SH_FIRST,2,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_NAXIS1],FITS_SH_FIRST,fb->rowsize,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_NAXIS2],FITS_SH_FIRST,fb->nrow,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_PCOUNT],FITS_SH_FIRST,0,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_GCOUNT],FITS_SH_FIRST,1,NULL); ret|=fits_headerset_set_integer(header,headers[HDR_TFIELDS],FITS_SH_FIRST,fb->nbfield,NULL); for ( i=0 ; inbfield && fb->bfields != NULL ; i++ ) { tb=&fb->bfields[i]; sprintf(chdr,"%s%d",headers[HDR_TFORM],i+1); sprintf(cfrm,"%d%c",tb->repeat,tb->form); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,cfrm,NULL); if ( tb->null[0] ) { sprintf(chdr,"%s%d",headers[HDR_TNULL],i+1); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,tb->null,NULL); } if ( tb->type[0] ) { sprintf(chdr,"%s%d",headers[HDR_TTYPE],i+1); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,tb->type,NULL); } if ( tb->unit[0] ) { sprintf(chdr,"%s%d",headers[HDR_TUNIT],i+1); ret|=fits_headerset_set_string(header,chdr,FITS_SH_FIRST,tb->unit,NULL); } if ( tb->scale.bscale != 1.0 || tb->scale.bzero != 0.0 ) { sprintf(chdr,"%s%d",headers[HDR_TSCAL],i+1); ret|=fits_headerset_set_double(header,chdr,FITS_SH_FIRST,tb->scale.bscale,NULL); sprintf(chdr,"%s%d",headers[HDR_TZERO],i+1); ret|=fits_headerset_set_double(header,chdr,FITS_SH_FIRST,tb->scale.bzero ,NULL); } } return(ret); } /*****************************************************************************/ int fits_bintable_write_cb(int (*cb_write)(void *,void *,int),void *param,fitsbtable *fb,int is_pad) { int wr; int i,psize; unsigned char *data; if ( fb==NULL || fb->data==NULL ) return(0); wr=0; data=(unsigned char *)malloc(fb->rowsize); for ( i=0 ; inrow ; i++ ) { memcpy(data,fb->data[i],fb->rowsize); fits_bintable_swap_line(data,fb->rowsize,fb->bfields,fb->nbfield); cb_write(param,data,fb->rowsize); wr+=fb->rowsize; } free(data); if ( is_pad && wr%FITS_TAPE_BLOCKSIZE>0 ) { psize=FITS_TAPE_BLOCKSIZE-(wr%FITS_TAPE_BLOCKSIZE); data=(unsigned char *)malloc(psize); memset(data,0,psize); cb_write(param,data,psize); wr+=psize; free(data); } return(wr); } int fits_bintable_write(FILE *fw,fitsbtable *fb,int is_pad) { return(fits_bintable_write_cb(fits_cb_write,(void *)fw,fb,is_pad)); } /*****************************************************************************/ int fits_bintable_free(fitsbtable *fb) { if ( fb->allocdata != NULL ) fits_tensor_free(fb->allocdata); fb->allocdata=NULL; fb->data=NULL; if ( fb->bfields != NULL && fb->nbfield>0 ) free(fb->bfields); fb->nbfield=0; fb->bfields=NULL; fb->nrow=0; fb->rowsize=0; fb->pcount=0; return(0); } /*****************************************************************************/ int fits_bintable_duplicate(fitsbtable *db,fitsbtable *sb,int flag) { int naxis[2]; db->nrow=sb->nrow; db->rowsize=sb->rowsize; db->nbfield=sb->nbfield; db->bfields=(fitsbfield *)malloc(sizeof(fitsbfield)*db->nbfield); memcpy(db->bfields,sb->bfields,sizeof(fitsbfield)*db->nbfield); naxis[0]=db->rowsize; naxis[1]=db->nrow; if ( db->data != NULL ) { db->data=fits_tensor_alloc_arr(1,2,naxis); memcpy(&db->data[0][0],&sb->data[0][0],db->rowsize*db->nrow); db->allocdata=db->data; } else { db->data=NULL; db->allocdata=NULL; } return(0); } /****************************************************************************** Reference: [1]: Definition of the Flexible Image Transport System (FITS) NASA / Science Office of Standards and Technology (NOST) NOST 100-2.0 (March 29, 1999) NASA Goddard Space Flight Center http://fits.gsfc.nasa.gov/fits_documentation.html [2]: Author's comment: this library contains the implementation of the unreferenced int64_t field 'K' as well. ******************************************************************************/ fitsh-0.9.2/libfits/Makefile.in0000644000175000017500000000252211657563500014765 0ustar apalapalSHELL=/bin/sh CC=@CC@ AR=@AR@ LD=@LD@ RANLIB=@RANLIB@ CFLAGS=@CFLAGS@ DLEXT=@DLEXT@ DLSWC=@DLSWC@ INC=../include all: libfits.a FITS_MODULES=\ fits-bintable.o \ fits-common.o \ fits-draw.o \ fits-header.o \ fits-image.o \ fits-table.o \ fits-ui.o \ fits-core.o .PHONY: all clean fits-common.o: fits-common.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-common.c fits-header.o: fits-header.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-header.c fits-image.o: fits-image.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-image.c fits-table.o: fits-table.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-table.c fits-bintable.o: fits-bintable.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-bintable.c fits-draw.o: fits-draw.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-draw.c fits-ui.o: fits-ui.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-ui.c fits-core.o: fits-core.c fits-common.h $(INC)/fits/fits.h $(CC) $(CFLAGS) -I$(INC) -c fits-core.c libfits.a: $(FITS_MODULES) $(AR) src libfits.a $(FITS_MODULES) $(RANLIB) libfits.a libfits.$(DLEXT): $(FITS_MODULES) $(CC) $(CFLAGS) -o libfits.$(DLEXT) $(DLSWC) $(FITS_MODULES) chmod -x libfits.$(DLEXT) clean: rm -f *.o *.a *.$(DLEXT) fitsh-0.9.2/libfits/fits-common.c0000644000175000017500000001212011236245632015306 0ustar apalapal/*****************************************************************************/ /* fits-common.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* Declaration of some global constants and common allocation functions. */ /* (c) 2004-06, Pal, A. (apal@szofi.elte.hu). */ /* See reference(s) at the end of this source code. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ char *headers[]= { "NAXIS" , /* 0 */ "NAXIS1" , /* 1 */ "NAXIS2" , /* 2 */ "NAXIS3" , /* 3 */ "NAXIS4" , /* 4 */ "BITPIX" , /* 5 */ "BSCALE" , /* 6 */ "BZERO" , /* 7 */ "EXTEND" , /* 8 */ "XTENSION", /* 9 */ "INHERIT" , /* 10 */ "SIMPLE" , /* 11 */ "ORIGIN" , /* 12 */ "GAIN" , /* 13 */ "END" , /* 14 */ "TFIELDS" , /* 15 */ "TBCOL" , /* 16 */ "TFORM" , /* 17 */ "TSCAL" , /* 18 */ "TZERO" , /* 19 */ "TNULL" , /* 20 */ "TTYPE" , /* 21 */ "TUNIT" , /* 22 */ "PCOUNT" , /* 23 */ "GCOUNT" , /* 24 */ NULL }; char *comment_fits_standard="Fits standard"; int substantial_headers[]= { HDR_SIMPLE, HDR_NAXIS, HDR_BITPIX, HDR_EXTEND, HDR_XTENSION, -1 }; /*****************************************************************************/ void *fits_tensor_alloc_arr(int typesize,int rank,int *arr) { int tsize,psize,bsize,cd,cb,snext,pnext; int i,j; void *ret,**pret; if ( rank<=0 ) return(NULL); psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { bsize=bsize*arr[i]; psize+=bsize; } psize=psize*sizeof(void *); tsize=psize+typesize*bsize*arr[0]; pret=(void **)malloc(tsize); if ( pret==NULL ) return(NULL); psize=0;bsize=1; for ( i=rank-1 ; i>=1 ; i-- ) { cd=arr[i]; if ( i>1 ) snext=sizeof(void *); else snext=typesize; cb=cd*bsize; pnext=psize+cb; for ( j=0 ; jbuffer=(char *)realloc(fmw->buffer,fmw->length+length); memcpy(fmw->buffer+fmw->length,src,length); fmw->length+=length; return(length); } else return(0); } /****************************************************************************** Reference: [1]: Definition of the Flexible Image Transport System (FITS) NASA / Science Office of Standards and Technology (NOST) NOST 100-2.0 (March 29, 1999) NASA Goddard Space Flight Center http://fits.gsfc.nasa.gov/fits_documentation.html ******************************************************************************/ fitsh-0.9.2/libfits/fits-header.c0000644000175000017500000004131411236245677015266 0ustar apalapal/*****************************************************************************/ /* fits-header.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* FITS header manipulation. */ /* (c) 2004-06, Pal, A. (apal@szofi.elte.hu). */ /* See reference(s) at the end of this source code. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ int fits_headerset_reset(fitsheaderset *header) { header->hdrs=NULL; header->nhdr=0; header->ahdr=0; return(0); } int fits_headerset_duplicate(fitsheaderset *ret,fitsheaderset *act) { ret->nhdr=act->nhdr; ret->ahdr=act->ahdr; ret->hdrs=(fitsheader *)malloc(sizeof(fitsheader)*(act->ahdr)); memcpy(ret->hdrs,act->hdrs,sizeof(fitsheader)*(act->nhdr)); return(0); } int fits_headerset_free(fitsheaderset *header) { if ( header->hdrs != NULL ) { free(header->hdrs); } fits_headerset_reset(header); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static fitsheader *fits_headerset_add(fitsheaderset *header) { fitsheader *fhd; if ( header->hdrs==NULL || header->nhdr==0 || header->ahdr==0 ) { header->hdrs=(fitsheader *)malloc(sizeof(fitsheader)*HDRBLOCKS); header->nhdr=0; header->ahdr=HDRBLOCKS; } else if ( header->nhdr+1 > header->ahdr ) { header->hdrs=(fitsheader *)realloc(header->hdrs,sizeof(fitsheader)*(header->ahdr+HDRBLOCKS)); header->ahdr+=HDRBLOCKS; } fhd=&header->hdrs[header->nhdr]; memset(fhd,0,sizeof(fitsheader)); header->nhdr++; return(fhd); } int fits_headerset_read_cb(int (*cb_read)(void *,void *,int),void *param,fitsheaderset *header) { char buff[2*FITS_TAPE_CARDIMAGESIZE]; char name[32],comment[2*FITS_TAPE_CARDIMAGESIZE]; int i,j,k,l,lin,type; int vint; double vdouble; char vstr[128]; fitsheader *fhd; lin=0; while ( 1 ) { /** Read the next 80 bytes from the stream. This block is **/ /** called "card image", see [1]. **/ i=cb_read(param,buff,FITS_TAPE_CARDIMAGESIZE); if ( i <=0 ) break; lin++; for ( i=0,k=0 ; ivtype=FITS_EMPTY; continue; } /** The card image is absolutely empty or contains the reserved **/ /** keyword "END". Both cases indicate the end of the header. **/ if ( k==FITS_TAPE_CARDIMAGESIZE || memcmp(buff,"END ",8)==0 ) { while ( lin % (FITS_TAPE_CARDIMAGECOUNT) ) { cb_read(param,buff,FITS_TAPE_CARDIMAGESIZE);lin++; }; break; } /** Otherwise, its a normal card image with some context. **/ else { /** First, the keyword should be read... **/ for ( i=0 ; i<8 && buff[i] != 32 ; i++ ) { name[i]=buff[i]; } /** Reset the target storage variables... **/ name[i]=0;j=0;type=0;vint=0; buff[FITS_TAPE_CARDIMAGESIZE]=0;comment[0]=0; /** Standard commentatory keywords: COMMENT and HISTORY **/ /** Any ASCII text after the 8th col. is acceptable. **/ if ( strcmp(name,"COMMENT")==0 || strcmp(name,"HISTORY")==0 ) { strcpy(vstr,buff+8); type=FITS_VCOMMENT; } /** The card image has an appropriate value field, **/ /** indicated by the substring "= " at the position 8. **/ else if ( memcmp(buff+8,"= ",2)==0 ) { for ( i=10 ; i0 && comment[strlen(comment)-1]==32 ) comment[strlen(comment)-1]=0; } j=0; for ( i=10 ; i0 && vstr[k-1]==32 ) k--,vstr[k]=0; if ( strcmp(vstr,"T")==0 ) type=FITS_VBOOLEAN,vint=1; else if ( strcmp(vstr,"F")==0 ) type=FITS_VBOOLEAN,vint=0; else type=FITS_VSTR; } } } /** Any other case: the card image is a commentatory **/ /** field without a value indicator. **/ else { strcpy(vstr,buff+8); type=FITS_VCOMMENT; } fhd=fits_headerset_add(header); fhd->vtype=type; if ( type==FITS_VINT || type==FITS_VBOOLEAN ) fhd->vint=vint; else if ( type==FITS_VDOUBLE ) fhd->vdouble=vdouble; else if ( type==FITS_VSTR || type==FITS_VCOMMENT ) strcpy(fhd->vstr,vstr); strcpy(fhd->name,name); strcpy(fhd->comment,comment); } }; if ( header->hdrs != NULL ) { int n; n=header->nhdr; while ( 0hdrs[n-1].vtype==FITS_EMPTY ) n--; header->nhdr=n; } return(0); } int fits_headerset_read(FILE *fr,fitsheaderset *header) { return(fits_headerset_read_cb(fits_cb_read,(void *)fr,header)); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fits_headerset_write_cb(int (*cb_write)(void *,void *,int),void *param,fitsheaderset *header) { char buff[256],val[256]; int i,j,k,align,ln; ln=0; for ( i=0 ; inhdr ; i++ ) { strncpy(buff,header->hdrs[i].name,8);buff[8]=0; while ( strlen(buff)<8 ) strcat(buff," "); align=0; switch ( header->hdrs[i].vtype ) { case FITS_VINT: sprintf(val,"%d",header->hdrs[i].vint); align=2; break; case FITS_VDOUBLE: sprintf(val,"%.15g", header->hdrs[i].vdouble); j=(int)header->hdrs[i].vdouble; if ( (double)j==header->hdrs[i].vdouble ) { strcat(val,"."); } align=2; break; case FITS_VSTR: if ( strcmp(header->hdrs[i].name,headers[HDR_XTENSION])==0 ) { sprintf(val,"'%-8s'",header->hdrs[i].vstr); } else { sprintf(val,"'%s'",header->hdrs[i].vstr); } align=1; break; case FITS_VBOOLEAN: if ( header->hdrs[i].vint ) strcpy(val,"T"); else strcpy(val,"F"); align=2; break; case FITS_VCOMMENT: strcpy(val,header->hdrs[i].vstr); align=3; break; case FITS_EMPTY: align=-1; break; } if ( ! align ) continue; if ( align<0 ) { memset(buff,32,FITS_TAPE_CARDIMAGESIZE); buff[FITS_TAPE_CARDIMAGESIZE]=0; } else if ( align==1 ) { strcat(buff,"= "); strcat(buff,val); } else if ( align==2 ) { strcat(buff,"= "); while ( strlen(buff)+strlen(val)<30 ) { strcat(buff," "); } strcat(buff,val); } else if ( align==3 ) { strcat(buff,val); } if ( header->hdrs[i].comment[0] && ( align==1 || align==2 ) ) { j=strlen(buff); k=strlen(header->hdrs[i].comment); while ( j<30 && j+k+3hdrs[i].comment); } buff[FITS_TAPE_CARDIMAGESIZE]=0; while ( strlen(buff)hdrs==NULL ) return(0); for ( i=0,n=0 ; inhdr ; i++ ) { if ( strcmp(header->hdrs[i].name,hdr)==0 ) n++; } return(n); } int fits_headerset_get_id(fitsheaderset *header,char *hdr,int cnt) { int i,n; if ( header==NULL || header->hdrs==NULL ) return(-1); for ( i=0,n=0 ; inhdr ; i++ ) { if ( strcmp(header->hdrs[i].name,hdr)==0 ) { if ( n==cnt ) return(i); else n++; } } return(-1); } fitsheader *fits_headerset_get_header(fitsheaderset *header,char *hdr,int cnt) { int i; i=fits_headerset_get_id(header,hdr,cnt); if ( i<0 ) return(NULL); else return(&header->hdrs[i]); } fitsheader *fits_headerset_get_uniq_header(fitsheaderset *header,char *hdr) { int i,cnt; cnt=fits_headerset_get_count(header,hdr); if ( cnt != 1 ) return(NULL); i=fits_headerset_get_id(header,hdr,0); if ( i<0 ) return(NULL); else return(&header->hdrs[i]); } int fits_headerset_get_as_double(fitsheaderset *header,char *hdr,double *ret,int is_ambigous_allowed) { int n; fitsheader *h; if ( ! is_ambigous_allowed ) { n=fits_headerset_get_count(header,hdr); if ( n != 1 ) return(1); } h=fits_headerset_get_header(header,hdr,0); if ( h==NULL ) return(1); if ( h->vtype == FITS_VINT ) { *ret=(double)h->vint; return(0); } else if ( h->vtype == FITS_VDOUBLE ) { *ret=h->vdouble; return(0); } else { return(1); } } fitsheader *fits_headerset_append(fitsheaderset *img) { fitsheader *hdr; if ( img->hdrs==NULL || img->nhdr==0 || img->ahdr==0 ) { img->hdrs=(fitsheader *)malloc(sizeof(fitsheader)*HDRBLOCKS); img->nhdr=0; img->ahdr=HDRBLOCKS; } else if ( img->nhdr+1 > img->ahdr ) { img->hdrs=(fitsheader *)realloc(img->hdrs,sizeof(fitsheader)*(img->ahdr+HDRBLOCKS)); img->ahdr+=HDRBLOCKS; } hdr=&img->hdrs[img->nhdr]; img->nhdr++; return(hdr); } fitsheader * fits_headerset_insert_to(fitsheaderset *img,int n) { if ( img->hdrs==NULL || img->nhdr==0 || img->ahdr==0 ) { img->hdrs=(fitsheader *)malloc(sizeof(fitsheader)*HDRBLOCKS); img->nhdr=1; img->ahdr=HDRBLOCKS; n=0; } else { if ( img->nhdr+1 > img->ahdr ) { img->hdrs=(fitsheader *)realloc(img->hdrs,sizeof(fitsheader)*(img->ahdr+HDRBLOCKS)); img->ahdr+=HDRBLOCKS; } if ( n>img->nhdr ) n=img->nhdr; if ( nnhdr ) { memmove(img->hdrs+n+1,img->hdrs+n,sizeof(fitsheader)*(img->nhdr-n)); } img->nhdr++; } return(&img->hdrs[n]); } fitsheader * fits_headerset_insert(fitsheaderset *img) { if ( img->hdrs==NULL || img->nhdr==0 || img->ahdr==0 ) { img->hdrs=(fitsheader *)malloc(sizeof(fitsheader)*HDRBLOCKS); img->nhdr=1; img->ahdr=HDRBLOCKS; } else { if ( img->nhdr+1 > img->ahdr ) { img->hdrs=(fitsheader *)realloc(img->hdrs,sizeof(fitsheader)*(img->ahdr+HDRBLOCKS)); img->ahdr+=HDRBLOCKS; } memmove(img->hdrs+1,img->hdrs,sizeof(fitsheader)*(img->nhdr)); img->nhdr++; } return(&img->hdrs[0]); } fitsheader *fits_headerset_set_any(fitsheaderset *img,char *hdr,int rule,char *comment) { fitsheader *hd; int n; n=fits_headerset_get_count(img,hdr); if ( rule==FITS_SH_FORCEFIRST || rule==FITS_SH_INSERT ) { if ( rule==FITS_SH_FORCEFIRST ) fits_headerset_delete_all(img,hdr); hd=fits_headerset_insert(img); strncpy(hd->name,hdr,15); hd->name[15]=0; hd->comment[0]=0; hd->vtype=0; } else if ( rule==FITS_SH_BEGIN ) { for ( n=0 ; nnhdr && img->hdrs != NULL ; n++ ) { if ( strcmp(img->hdrs[n].name,headers[HDR_SIMPLE])==0 ) continue; else if ( strcmp(img->hdrs[n].name,headers[HDR_XTENSION])==0 ) continue; else if ( memcmp(img->hdrs[n].name,headers[HDR_NAXIS],5)==0 ) continue; else if ( strcmp(img->hdrs[n].name,headers[HDR_BITPIX])==0 ) continue; else if ( strcmp(img->hdrs[n].name,headers[HDR_EXTEND])==0 ) continue; else break; } hd=fits_headerset_insert_to(img,n); strncpy(hd->name,hdr,15); hd->name[15]=0; hd->comment[0]=0; hd->vtype=0; } else if ( n==0 || rule==FITS_SH_ADD ) { hd=fits_headerset_append(img); strncpy(hd->name,hdr,15); hd->name[15]=0; hd->comment[0]=0; hd->vtype=0; } else { if ( rule==FITS_SH_FIRST ) hd=fits_headerset_get_header(img,hdr,0); else if ( rule==FITS_SH_LAST ) hd=fits_headerset_get_header(img,hdr,n-1); else hd=NULL; } if ( comment != NULL && hd != NULL ) { strncpy(hd->comment,comment,79); hd->comment[79]=0; } return(hd); } int fits_headerset_set_integer(fitsheaderset *img,char *hdr,int rule,int val,char *comment) { fitsheader *hd; hd=fits_headerset_set_any(img,hdr,rule,comment); hd->vtype=FITS_VINT; hd->vint=val; return(0); } int fits_headerset_set_double(fitsheaderset *img,char *hdr,int rule,double val,char *comment) { fitsheader *hd; hd=fits_headerset_set_any(img,hdr,rule,comment); hd->vtype=FITS_VDOUBLE; hd->vdouble=val; return(0); } int fits_headerset_set_string(fitsheaderset *img,char *hdr,int rule,char *str,char *comment) { fitsheader *hd; hd=fits_headerset_set_any(img,hdr,rule,comment); hd->vtype=FITS_VSTR; strncpy(hd->vstr,str,69); hd->vstr[68]=0; return(0); } int fits_headerset_set_boolean(fitsheaderset *img,char *hdr,int rule,int vbool,char *comment) { fitsheader *hd; hd=fits_headerset_set_any(img,hdr,rule,comment); hd->vtype=FITS_VBOOLEAN; hd->vint=vbool; return(0); } /*****************************************************************************/ int fits_headerset_delete(fitsheaderset *img,char *hdr,int k) { int id,n; n=fits_headerset_get_count(img,hdr); if ( n<=0 || k>=n ) return(1); id=fits_headerset_get_id(img,hdr,k); memmove(img->hdrs+id,img->hdrs+id+1,(img->nhdr-id-1)*sizeof(fitsheader)); img->nhdr--; return(0); } int fits_headerset_delete_all(fitsheaderset *img,char *hdr) { int id,n; n=fits_headerset_get_count(img,hdr); while ( n>0 ) { n--; id=fits_headerset_get_id(img,hdr,n); memmove(img->hdrs+id,img->hdrs+id+1,(img->nhdr-id-1)*sizeof(fitsheader)); img->nhdr--; } return(0); } /*****************************************************************************/ int fits_headerset_copy(fitsheaderset *im1,fitsheaderset *im2) { if ( im1->hdrs != NULL ) free(im1->hdrs); im1->nhdr=im1->ahdr=0; im1->hdrs=(fitsheader *)malloc(sizeof(fitsheader)*im2->ahdr); memcpy(im1->hdrs,im2->hdrs,sizeof(fitsheader)*im2->nhdr); im1->nhdr=im2->nhdr; im1->ahdr=im2->ahdr; return(0); } /*****************************************************************************/ int fits_headerset_merge(fitsheaderset *ximg,fitsheaderset *img,int inherit) { int i,id,cnt,is_inherit; fitsheader *hdr; fits_headerset_delete_all(ximg,headers[HDR_XTENSION]); fits_headerset_set_boolean(ximg,headers[HDR_EXTEND],FITS_SH_INSERT,0,comment_fits_standard); fits_headerset_set_boolean(ximg,headers[HDR_SIMPLE],FITS_SH_INSERT,1,comment_fits_standard); if ( inherit<0 ) return(0); cnt=fits_headerset_get_count(ximg,headers[HDR_INHERIT]); if ( cnt>0 ) hdr=fits_headerset_get_header(ximg,headers[HDR_INHERIT],0); else hdr=NULL; is_inherit=(hdr != NULL && hdr->vtype==FITS_VBOOLEAN && hdr->vint && img != NULL); if ( ! is_inherit && ! inherit ) return(0); id=fits_headerset_get_id(img,headers[HDR_EXTEND],0); if ( id<0 ) return(0); for ( i=id+1 ; inhdr ; i++ ) { hdr=fits_headerset_append(ximg); if ( strcmp(img->hdrs[i].name,headers[HDR_INHERIT]) ) { memcpy(hdr,&img->hdrs[i],sizeof(fitsheader)); } } fits_headerset_delete_all(ximg,headers[HDR_INHERIT]); return(0); } /*****************************************************************************/ int fits_headerset_is_extension(fitsheaderset *header) { fitsheader *hx; char *p; if ( header->nhdr <= 0 ) return(-1); else if ( header->hdrs==NULL ) return(-1); hx=&header->hdrs[0]; if ( hx != NULL && hx->vtype==FITS_VSTR ) { p=strchr(hx->vstr,' '); if ( p != NULL ) *p=0; if ( strcmp(hx->vstr,"IMAGE")==0 ) return(FITS_EXT_IMAGE); else if ( strcmp(hx->vstr,"TABLE")==0 ) return(FITS_EXT_TABLE); else if ( strcmp(hx->vstr,"BINTABLE")==0 ) return(FITS_EXT_BINTABLE); else return(-1); } else return(-1); } /*****************************************************************************/ fitsh-0.9.2/libfits/fits-core.c0000644000175000017500000005230411236245655014763 0ustar apalapal/*****************************************************************************/ /* fits-core.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* Core procedures, functions and some wrappers for backward compatibility */ /* (and of course for simpler usage...) */ /* (c) 2004-06, Pal, A. (apal@szofi.elte.hu). */ /* See reference(s) at the end of this source code. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ int fits_tapeblock_size(int size) { size=(size+FITS_TAPE_BLOCKSIZE-1)/FITS_TAPE_BLOCKSIZE; return(size*FITS_TAPE_BLOCKSIZE); } /*****************************************************************************/ int fits_alloc_image(fits *img,int sx,int sy) { int ret; ret=fits_image_alloc(&img->i,sx,sy); return(ret); } int fits_alloc_image_gen(fits *img,int dim,int *pnaxis) { int ret; ret=fits_image_alloc_gen(&img->i,dim,pnaxis); return(ret); } int fits_alloc_image_2d(fits *img,int sx,int sy) { return ( fits_alloc_image(img,sx,sy) ); } int fits_alloc_image_3d(fits *img,int sx,int sy,int sz) { int pnaxis[3]; pnaxis[0]=sx, pnaxis[1]=sy, pnaxis[2]=sz; return ( fits_alloc_image_gen(img,3,pnaxis) ); } /*****************************************************************************/ fits *fits_create(void) { fits *ret; ret=(fits *)malloc(sizeof(fits)); if ( ret==NULL ) return(NULL); fits_headerset_reset(&ret->header); /* Empty header */ ret->i.bit=0; ret->i.sx=0; ret->i.sy=0; /* No primary image */ ret->i.data=NULL; ret->i.dim=0; /* No primary image */ ret->i.vdata=NULL; ret->i.allocdata=NULL; ret->i.read.bscale=ret->i.curr.bscale=1.0; /* default scaling parameters */ ret->i.read.bzero =ret->i.curr.bzero =0.0; /* default scaling parameters */ ret->length=0; ret->rawdata=NULL; /* No raw data. */ ret->xtns=NULL; /* No extensions */ ret->nxtn=0; return(ret); } static fits *fits_duplicate_native(fits *img,int flag) { fits *ret; int i; fitsimage *si,*di; fitsttable *st,*dt; fitsbtable *sb,*db; if ( img==NULL ) { ret=fits_create(); return(ret); } ret=(fits *)malloc(sizeof(fits)); if ( ret==NULL ) return(NULL); fits_headerset_duplicate(&ret->header,&img->header); fits_image_duplicate(&ret->i,&img->i,flag); if ( img->rawdata != NULL ) { ret->length=img->length; ret->rawdata=(char *)malloc(img->length); if ( flag ) memcpy(ret->rawdata,img->rawdata,img->length); else memset(ret->rawdata,0,img->length); } else { ret->length=0; ret->rawdata=NULL; } if ( img->nxtn>0 && img->xtns != NULL ) { ret->nxtn=img->nxtn; ret->xtns=(fitsextension *)malloc(sizeof(fitsextension)*ret->nxtn); for ( i=0 ; inxtn ; i++ ) { ret->xtns[i].type=img->xtns[i].type; fits_headerset_duplicate(&ret->xtns[i].header,&img->xtns[i].header); switch ( ret->xtns[i].type ) { case FITS_EXT_IMAGE: si=&img->xtns[i].x.i; di=&ret->xtns[i].x.i; fits_image_duplicate(di,si,flag); break; case FITS_EXT_TABLE: st=&img->xtns[i].x.t; dt=&ret->xtns[i].x.t; fits_table_duplicate(dt,st,flag); break; case FITS_EXT_BINTABLE: sb=&img->xtns[i].x.b; db=&ret->xtns[i].x.b; fits_bintable_duplicate(db,sb,flag); break; } } } else { ret->nxtn=0; ret->xtns=NULL; } return(ret); } fits *fits_duplicate(fits *img) { fits *ret; ret=fits_duplicate_native(img,1); return(ret); } fits *fits_duplicate_empty(fits *img) { fits *ret; ret=fits_duplicate_native(img,0); return(ret); } void fits_free_image(fits *img) { fits_image_free(&img->i); } void fits_free(fits *img) { int i; fits_headerset_free(&img->header); fits_free_image(img); if ( img->rawdata != NULL ) { free(img->rawdata); img->length=0; } for ( i=0 ; inxtn && img->xtns != NULL ; i++ ) { fits_headerset_free(&img->xtns[i].header); switch ( img->xtns[i].type ) { case FITS_EXT_IMAGE: fits_image_free(&img->xtns[i].x.i); break; case FITS_EXT_TABLE: fits_table_free(&img->xtns[i].x.t); break; case FITS_EXT_BINTABLE: fits_bintable_free(&img->xtns[i].x.b); break; } } if ( img->xtns != NULL ) free(img->xtns); free(img); } /*****************************************************************************/ int fits_read_header(FILE *fr,fits *img) { int ret; ret=fits_headerset_read_cb(fits_cb_read,(void *)fr,&img->header); return(ret); } /*****************************************************************************/ int fits_get_header_count(fits *img,char *hdr) { int n; n=fits_headerset_get_count(&img->header,hdr); return(n); } int fits_get_header_id(fits *img,char *hdr,int cnt) { int i; i=fits_headerset_get_id(&img->header,hdr,cnt); return(i); } fitsheader * fits_get_header(fits *img,char *hdr,int cnt) { fitsheader *h; h=fits_headerset_get_header(&img->header,hdr,cnt); return(h); } int fits_get_header_as_double(fits *img,char *hdr,double *ret,int is_ambigous_allowed) { int r; r=fits_headerset_get_as_double(&img->header,hdr,ret,is_ambigous_allowed); return(r); } int fits_get_gain(fits *img,double *ret) { int r; r=fits_get_header_as_double(img,headers[HDR_GAIN],ret,0); return(r); } /*****************************************************************************/ fitsheader *fits_set_header_any(fits *img,char *hdr,int rule,char *comment) { fitsheader *hd; hd=fits_headerset_set_any(&img->header,hdr,rule,comment); return(hd); } int fits_set_header_integer(fits *img,char *hdr,int rule,int val,char *comment) { int ret; ret=fits_headerset_set_integer(&img->header,hdr,rule,val,comment); return(ret); } int fits_set_header_double(fits *img,char *hdr,int rule,double val,char *comment) { int ret; ret=fits_headerset_set_double(&img->header,hdr,rule,val,comment); return(ret); } int fits_set_header_string(fits *img,char *hdr,int rule,char *str,char *comment) { int ret; ret=fits_headerset_set_string(&img->header,hdr,rule,str,comment); return(ret); } int fits_set_header_boolean(fits *img,char *hdr,int rule,int vbool,char *comment) { int ret; ret=fits_headerset_set_boolean(&img->header,hdr,rule,vbool,comment); return(ret); } /*****************************************************************************/ int fits_delete_header(fits *img,char *hdr,int k) { int ret; ret=fits_headerset_delete(&img->header,hdr,k); return(ret); } int fits_delete_all_header(fits *img,char *hdr) { int ret; ret=fits_headerset_delete_all(&img->header,hdr); return(ret); } /*****************************************************************************/ void fits_copy_full_header(fits *im1,fits *im2) { fits_headerset_copy(&im1->header,&im2->header); } /*****************************************************************************/ int fits_set_image(fits *img,double value) { fits_image_set_value(&img->i,value); return(0); } int fits_reset_image(fits *img) { fits_image_reset(&img->i); return(0); } /*****************************************************************************/ int fits_read_image_line(FILE *f,int sx,int bit,double *line) { int ret; ret=fits_image_read_line(f,sx,bit,line); return(ret); } /*****************************************************************************/ int fits_get_scale(fits *img,double *rbscale,double *rbzero) { int ret; ret=fits_image_get_scale(&img->header,&img->i,rbscale,rbzero); return(ret); } int fits_get_image_params(fits *img) { int ret; ret=fits_image_get_params(&img->header,&img->i); return(ret); } /*****************************************************************************/ int fits_rescale(fits *img) { int ret; ret=fits_image_rescale(&img->i); return(ret); } int fits_backscale(fits *img,double ibscale,double ibzero) { int ret; ret=fits_image_backscale(&img->i,ibscale,ibzero); return(ret); } int fits_set_image_params(fits *img) { int ret; ret=fits_image_set_params(&img->header,&img->i); return(ret); } /*****************************************************************************/ int fits_set_standard(fits *img,char *comment) { if ( comment==NULL ) comment="FITS standard"; fits_headerset_set_boolean(&img->header,headers[HDR_SIMPLE], FITS_SH_FORCEFIRST,1,comment); return(0); } int fits_set_origin(fits *img,char *origin,char *comment) { fits_headerset_set_string(&img->header,headers[HDR_ORIGIN], FITS_SH_FIRST,origin,comment); return(0); } int fits_set_extend(fits *img,int flag,char *comment) { fits_headerset_set_boolean(&img->header,headers[HDR_EXTEND], FITS_SH_ADD,flag,comment); return(0); } /*****************************************************************************/ int fits_read_image(FILE *fr,fits *img) { int ret; ret=fits_image_read(fr,&img->i); return(ret); } int fits_read_rawdata(FILE *fr,fits *img) { int rd,length; char *data; data=(char *)malloc(BUFSIZE); length=0; while ( ! feof(fr) ) { rd=fread(data+length,1,BUFSIZE,fr); if ( rd==0 ) break; length+=rd; if ( ! feof(fr) ) data=(char *)realloc(data,length+BUFSIZE); } data=(char *)realloc(data,length); img->i.data=NULL; img->i.sx=img->i.sy=0; img->i.dim=0; img->i.vdata=NULL; img->rawdata=data, img->length=length; return(0); } /*****************************************************************************/ fitsextension *fits_extension_add(fits *img,int cnt) { fitsextension *fx; img->xtns=(fitsextension *)realloc(img->xtns,sizeof(fitsextension)*(img->nxtn+cnt)); fx=&img->xtns[img->nxtn]; memset(fx,0,sizeof(fitsextension)*cnt); img->nxtn+=cnt; return(fx); } fitsextension *fits_extension_new(fits *img,int type) { fitsextension *fx; fx=fits_extension_add(img,1); fx->type=type; return(fx); } /*****************************************************************************/ int fits_read_extension_image_cb(int (*cb_read)(void *,void *,int),void *param,fitsextension *xtn) { int ret; ret=fits_image_get_params(&xtn->header,&xtn->x.i); if ( ret ) return(ret); ret=fits_image_alloc_gen(&xtn->x.i,xtn->x.i.dim,xtn->x.i.naxis); if ( ret ) return(ret); ret=fits_image_read_cb(cb_read,param,&xtn->x.i); return(ret); } int fits_read_extension_image(FILE *fr,fitsextension *xtn) { return(fits_read_extension_image_cb(fits_cb_read,(void *)fr,xtn)); } int fits_read_extension_table_cb(int (*cb_read)(void *,void *,int),void *param,fitsextension *xtn) { int ret; ret=fits_table_get_params(&xtn->header,&xtn->x.t); if ( ret ) return(ret); ret=fits_table_alloc(&xtn->x.t); if ( ret ) return(ret); ret=fits_table_read_cb(cb_read,param,&xtn->x.t); return(ret); } int fits_read_extension_table(FILE *fr,fitsextension *xtn) { return(fits_read_extension_table_cb(fits_cb_read,(void *)fr,xtn)); } int fits_read_extension_bintable_cb(int (*cb_read)(void *,void *,int),void *param,fitsextension *xtn) { int ret; ret=fits_bintable_get_params(&xtn->header,&xtn->x.b); if ( ret ) return(ret); ret=fits_bintable_alloc(&xtn->x.b); if ( ret ) return(ret); ret=fits_bintable_read_cb(cb_read,param,&xtn->x.b); return(ret); } int fits_read_extension_bintable(FILE *fr,fitsextension *xtn) { return(fits_read_extension_bintable_cb(fits_cb_read,(void *)fr,xtn)); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fits_skip_extension_image_cb(int (*cb_read)(void *,void *,int),void *param,fitsextension *xtn) { int ret; ret=fits_image_get_params(&xtn->header,&xtn->x.i); if ( ret ) return(ret); ret=fits_image_skip_cb(cb_read,param,&xtn->x.i); return(ret); } int fits_skip_extension_table_cb(int (*cb_read)(void *,void *,int),void *param,fitsextension *xtn) { int ret; ret=fits_table_get_params(&xtn->header,&xtn->x.t); if ( ret ) return(ret); ret=fits_table_skip_cb(cb_read,param,&xtn->x.t); return(ret); } int fits_skip_extension_bintable_cb(int (*cb_read)(void *,void *,int),void *param,fitsextension *xtn) { int ret; ret=fits_bintable_get_params(&xtn->header,&xtn->x.b); if ( ret ) return(ret); ret=fits_bintable_skip_cb(cb_read,param,&xtn->x.b); return(ret); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int fits_read_extensions_cb(int (*cb_read)(void *,void *,int),void *param,fits *img) { fitsextension xtn; int type; while ( 1 ) { xtn.type=0; fits_headerset_reset(&xtn.header); fits_headerset_read_cb(cb_read,param,&xtn.header); if ( xtn.header.nhdr<=0 ) break; type=fits_headerset_is_extension(&xtn.header); xtn.type=type; switch ( type ) { case FITS_EXT_IMAGE: fits_read_extension_image_cb(cb_read,param,&xtn); break; case FITS_EXT_TABLE: fits_read_extension_table_cb(cb_read,param,&xtn); break; case FITS_EXT_BINTABLE: fits_read_extension_bintable_cb(cb_read,param,&xtn); break; default: fits_headerset_free(&xtn.header); return(1); break; } img->xtns=(fitsextension *)realloc(img->xtns,sizeof(fitsextension)*(img->nxtn+1)); memcpy(&img->xtns[img->nxtn],&xtn,sizeof(fitsextension)); img->nxtn++; }; return(0); } fits *fits_read_cb(int (*cb_read)(void *,void *,int),void *param) { fits *img; int i; fitsimage *fi; fitsheader *hx; img=fits_create(); if ( img==NULL ) return(NULL); fits_headerset_reset(&img->header); fits_headerset_read_cb(cb_read,param,&img->header); fi=&img->i; i=fits_image_get_params(&img->header,fi); if ( ! i ) { i=fits_image_alloc_gen(fi,fi->dim,fi->naxis); if ( i ) { fits_free(img); return(NULL); } fits_image_read_cb(cb_read,param,fi); } /*** else { i=fits_read_rawdata(fr,img); if ( i ) { fits_free(img); return(NULL); } } ***/ hx=fits_headerset_get_uniq_header(&img->header,headers[HDR_EXTEND]); if ( hx != NULL && hx->vtype==FITS_VBOOLEAN && hx->vint ) { fits_read_extensions_cb(cb_read,param,img); } return(img); } fits *fits_read(FILE *fr) { return(fits_read_cb(fits_cb_read,(void *)fr)); } /*****************************************************************************/ int fits_skip_more_extensions_cb(int (*cb_read)(void *,void *,int),void *param,int nframe) { fitsextension xtn; int type; while ( nframe>0 ) { fits_headerset_reset(&xtn.header); fits_headerset_read_cb(cb_read,param,&xtn.header); if ( xtn.header.nhdr<=0 ) break; type=fits_headerset_is_extension(&xtn.header); switch ( type ) { case FITS_EXT_IMAGE: fits_skip_extension_image_cb(cb_read,param,&xtn); break; case FITS_EXT_TABLE: fits_skip_extension_table_cb(cb_read,param,&xtn); break; case FITS_EXT_BINTABLE: fits_skip_extension_bintable_cb(cb_read,param,&xtn); break; default: fits_headerset_free(&xtn.header); break; } nframe--; }; return(0); } int fits_skip_more_extensions(FILE *fr,int nframe) { return(fits_skip_more_extensions_cb(fits_cb_read,(void *)fr,nframe)); } fits * fits_read_frame_as_extension_cb(int (*cb_read)(void *,void *,int),void *param,int frameno) { fits *img; int i,type; fitsheaderset header; fitsimage priimg; fitsextension *fx,xtn; if ( frameno<0 ) return(NULL); /* invalid frame number */ if ( cb_read==NULL ) return(NULL); /* invalid callback */ img=fits_create(); fits_headerset_reset(&header); fits_headerset_read_cb(cb_read,param,&header); i=fits_image_get_params(&header,&priimg); if ( ! i ) /* valid image */ { if ( frameno==0 ) { fits_image_alloc_gen(&priimg,priimg.dim,priimg.naxis); fits_image_read_cb(cb_read,param,&priimg); fx=fits_extension_add(img,1); memcpy(&fx->header,&header,sizeof(fitsheaderset)); fx->type=FITS_EXT_IMAGE; memcpy(&fx->x.i,&priimg,sizeof(fitsimage)); return(img); } else fits_image_skip_cb(cb_read,param,&priimg); frameno--; } fits_headerset_free(&header); fits_skip_more_extensions_cb(cb_read,param,frameno); fits_headerset_reset(&xtn.header); fits_headerset_read_cb(cb_read,param,&xtn.header); type=fits_headerset_is_extension(&xtn.header); switch ( type ) { case FITS_EXT_IMAGE: fits_read_extension_image_cb(cb_read,param,&xtn); break; case FITS_EXT_TABLE: fits_read_extension_table_cb(cb_read,param,&xtn); break; case FITS_EXT_BINTABLE: fits_read_extension_bintable_cb(cb_read,param,&xtn); break; default: fits_headerset_free(&xtn.header); return(NULL); break; } xtn.type=type; fx=fits_extension_add(img,1); memcpy(fx,&xtn,sizeof(fitsextension)); return(img); } fits * fits_read_frame_as_extension(FILE *fr,int frameno) { return(fits_read_frame_as_extension_cb(fits_cb_read,(void *)fr,frameno)); } fits * fits_seek_frame_to_image_cb(int (*cb_read)(void *,void *,int),void *param,int frameno) { fits *img; int i,type; fitsheaderset header; if ( frameno<0 ) return(NULL); /* invalid frame number */ img=fits_create(); fits_headerset_reset(&img->header); fits_headerset_read_cb(cb_read,param,&img->header); if ( img->header.nhdr<=0 || img->header.hdrs==NULL ) { fits_free(img); return(0); } i=fits_image_get_params(&img->header,&img->i); if ( ! i ) /* valid image */ { if ( frameno==0 ) return(img); else { fits_image_skip_cb(cb_read,param,&img->i); frameno--; } } fits_skip_more_extensions_cb(cb_read,param,frameno); fits_headerset_reset(&header); fits_headerset_read_cb(cb_read,param,&header); type=fits_headerset_is_extension(&header); if ( type==FITS_EXT_IMAGE ) { fits_image_get_params(&header,&img->i); fits_headerset_merge(&img->header,&header,0); return(img); } else { fits_headerset_free(&header); fits_headerset_free(&img->header); fits_free(img); return(NULL); } return(img); } fits * fits_seek_frame_to_image(FILE *fr,int frameno) { return(fits_seek_frame_to_image_cb(fits_cb_read,(void *)fr,frameno)); } fits * fits_read_frame_to_image_cb(int (*cb_read)(void *,void *,int),void *param,int frameno) { fits *img; if ( frameno<0 ) frameno=0; img=fits_seek_frame_to_image_cb(cb_read,param,frameno); if ( img==NULL ) return(NULL); fits_image_alloc_gen(&img->i,img->i.dim,img->i.naxis); fits_image_read_cb(cb_read,param,&img->i); return(img); } fits * fits_read_frame_to_image(FILE *fr,int frameno) { return(fits_read_frame_to_image_cb(fits_cb_read,(void *)fr,frameno)); } /*****************************************************************************/ fits *fits_read_raw(FILE *fr) { fits *img; int i; img=fits_create(); if ( img==NULL ) return(NULL); fits_headerset_reset(&img->header); fits_headerset_read(fr,&img->header); i=fits_read_rawdata(fr,img); if ( i ) { fits_free(img); return(NULL); } return(img); } /*****************************************************************************/ int fits_write_header(FILE *fw,fits *img) { int ret; ret=fits_headerset_write(fw,&img->header); return(ret); } /*****************************************************************************/ int fits_write_image_line(FILE *fw,int sx,int bit,double *line) { int ret; ret=fits_image_write_line(fw,sx,bit,line); return(ret); } int fits_write_image(FILE *fw,fits *img) { int wr; wr=fits_image_write(fw,&img->i,0); return(wr); /* total bytes written */ } int fits_write_cb(int (*cb_write)(void *,void *,int),void *param,fits *img) { int wr,wn; char *wbuff; int i,j,validimg; wr=fits_headerset_write_cb(cb_write,param,&img->header); validimg=1; for ( i=0 ; ii.dim ; i++ ) { if ( img->i.naxis[i] <= 0 ) validimg=0; } if ( img->i.vdata != NULL && img->i.dim>0 && validimg ) { wr+=fits_image_write_cb(cb_write,param,&img->i,1); /* pad image */ } for ( i=0 ; inxtn && img->xtns != NULL ; i++ ) { wr+=fits_headerset_write_cb(cb_write,param,&img->xtns[i].header); switch ( img->xtns[i].type ) { case FITS_EXT_IMAGE: wr+=fits_image_write_cb(cb_write,param,&img->xtns[i].x.i,1); break; case FITS_EXT_TABLE: wr+=fits_table_write_cb(cb_write,param,&img->xtns[i].x.t,1); break; case FITS_EXT_BINTABLE: wr+=fits_bintable_write_cb(cb_write,param,&img->xtns[i].x.b,1); break; } } if ( img->rawdata != NULL && img->length>0 ) { for ( i=0 ; ilength ; ) { j=BUFSIZE; if ( img->length-ilength-i; cb_write(param,img->rawdata+i,j); wr+=j;i+=j; } wn=FITS_TAPE_BLOCKSIZE-(wr%FITS_TAPE_BLOCKSIZE); if ( wn==FITS_TAPE_BLOCKSIZE ) return(wr); wbuff=(char *)malloc(wn); memset(wbuff,0,wn); cb_write(param,wbuff,wn); wr+=wn; free(wbuff); } return(wr); } int fits_write(FILE *fw,fits *img) { return(fits_write_cb(fits_cb_write,(void *)fw,img)); } int fits_mem_write(void **rbuff,fits *img) { fitsmemwrite fmw; int length; if ( rbuff==NULL ) return(0); fmw.buffer=NULL; fmw.length=0; length=fits_write_cb(fits_cb_mem_write,(void *)(&fmw),img); *rbuff=(void *)fmw.buffer; return(length); } /*****************************************************************************/ double * fits_dump_image_raw(fits *img) { double *ret; ret=fits_image_dump(&img->i); return(ret); } /****************************************************************************** Reference: [1]: Definition of the Flexible Image Transport System (FITS) NASA / Science Office of Standards and Technology (NOST) NOST 100-2.0 (March 29, 1999) NASA Goddard Space Flight Center http://fits.gsfc.nasa.gov/fits_documentation.html ******************************************************************************/ fitsh-0.9.2/libfits/fits-draw.c0000644000175000017500000000702011236245666014765 0ustar apalapal/*****************************************************************************/ /* fits-draw.c */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Another simple standalone library for manipulating FITS files: */ /* Drawing pixels, circles and lines to 2-dimensional images. */ /* (c) 2004-06, Pal, A. (apal@szofi.elte.hu). */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* See function prototypes and the usage of the functions in fits.h */ /*****************************************************************************/ #include #include #include #include #include #define _FITS_SOURCE #include #include "fits-common.h" /*****************************************************************************/ int fits_image_draw_pixel(fitsimage *img,int x,int y,double c) { if ( img==NULL || img->vdata==NULL ) return(1); if ( img->data==NULL || img->dim != 2 ) return(1); if ( x<0 || y<0 || x>=img->sx || y>=img->sy ) return(0); img->data[y][x]=c; return(0); } int fits_image_draw_pixel_nochk(fitsimage *img,int x,int y,double c) { if ( x<0 || y<0 || x>=img->sx || y>=img->sy ) return(0); img->data[y][x]=c; return(0); } int fits_image_draw_line(fitsimage *img,int x,int y,int dx,int dy,double col,int style) { int sx,sy,s,n; if ( img==NULL || img->vdata==NULL ) return(1); if ( img->data==NULL || img->dim != 2 ) return(1); style = style & 0xffff; style = style | (style<<16); if ( style & 1 ) fits_image_draw_pixel_nochk(img,x,y,col); dx-=x,dy-=y; if ( dx==0 && dy==0 ) return(0); if ( dx<0 ) dx=-dx,sx=-1; else sx=+1; if ( dy<0 ) dy=-dy,sy=-1; else sy=+1; if ( dx>=dy ) { for ( s=dx/2,n=dx ; n ; n-- ) { style=(style<<1)|((style>>31)&1); if ( style & 1 ) fits_image_draw_pixel_nochk(img,x,y,col); s+=dy; if ( s>=dx ) y+=sy,s-=dx; x+=sx; }; } else { for ( s=dy/2,n=dy ; n ; n-- ) { style=(style<<1)|((style>>31)&1); if ( style & 1 ) fits_image_draw_pixel_nochk(img,x,y,col); s+=dx; if ( s>=dy ) x+=sx,s-=dy; y+=sy; }; } return(0); } int fits_image_draw_circle(fitsimage *img,int x,int y,int r,double col) { int a,b,c,d,dx,dy; if ( img==NULL || img->vdata==NULL ) return(1); if ( img->data==NULL || img->dim != 2 ) return(1); dx=r,dy=0; a=2*r-1,b=1,c=3,d=2*r-3; while ( dx>=dy ) { fits_image_draw_pixel_nochk(img,x+dx,y+dy,col); fits_image_draw_pixel_nochk(img,x+dx,y-dy,col); fits_image_draw_pixel_nochk(img,x-dx,y+dy,col); fits_image_draw_pixel_nochk(img,x-dx,y-dy,col); if ( dx != dy ) { fits_image_draw_pixel_nochk(img,x+dy,y+dx,col); fits_image_draw_pixel_nochk(img,x+dy,y-dx,col); fits_image_draw_pixel_nochk(img,x-dy,y+dx,col); fits_image_draw_pixel_nochk(img,x-dy,y-dx,col); } if ( a>=b ) b+=c,c+=2,dy++; if ( a<=b ) a+=d,d-=2,dx--; }; return(0); } /*****************************************************************************/ int fits_draw_pixel(fits *img,int x,int y,double c) { int ret; ret=fits_image_draw_pixel(&img->i,x,y,c); return(ret); } int fits_draw_line(fits *img,int x,int y,int dx,int dy,double col,int style) { int ret; ret=fits_image_draw_line(&img->i,x,y,dx,dy,col,style); return(ret); } int fits_draw_circle(fits *img,int x,int y,int r,double col) { int ret; ret=fits_image_draw_circle(&img->i,x,y,r,col); return(ret); } /*****************************************************************************/ fitsh-0.9.2/man/0000755000175000017500000000000012771772047012044 5ustar apalapalfitsh-0.9.2/man/ficonv.1.gz0000644000175000017500000000303712772016327014025 0ustar apalapal‹×èWficonv.1­WYoÛF~篘êI$ú¨4‰+$q[h,–R ( d%Å­I.³»”ìüúΣ„/E±†“ðú'áóðì•™OèéÇ#šÿ hí¥È 4V½ œÝÀäõíUà÷EC ÍxÁ‹ÐÀ5Ë*¦Í«Y ²JsQ€–¬P‰93¯ÊâÌ>N¦w³ñ,߀ƒ ~’q4¥]GÉýàÆ†.$&(±Xâh{ŠÃ/ÊJï ¸•nÇ­Ñ·W³ËûñÝ|<ó¡¬d)‚H@§\A)ÅJ²èQoD"²8„w\*=€JY‘Ðа‚­eòñ|².!nu¯ëŠp5iKEž5n·QäTY )•^(_%–ܶì¥À„tpbD{’-ñµC%•VaêØ†S¡Ò[æj3y¥tMÑW­k©«ÝuÈïO…T¢Çí°®½¾%ŸÑJ¥… –hª¾Š®××’m ‰e7ž<Çý‘a]’ãoÆ·[]«0½•îJ l¸N»²š>ÐwKÓ+¸m, NSÿ×\TÊ$ é2º©•¦©º>Áï/×Κ>QI"b8ê£CÇ£ªÝ–ú€R{1Oj% ÔÄb÷r`ù´Aa4î¨ï¤ëúšúq4Ôâ€]òb§‡û¤4éldÒ$í¤7ß¾[»¤5v{ æL=øXÔjŒ­3è°m3¶ÌÌ£?^ÇÍ,ê(Ùªí\››²½ZZ1Íë(øàÚ¿Z£½+4A ñO\Úão#*ãtö%ÄL…æröÈó*‡¢²×kZØâ×€B¥õ’G'?mõ®ºBµTWCC…ú4®}Æ*¾ÊÙ(¸ohÚ)S„”&`&cj˜kîÚRUOCwï8XO¡ŒB¼¾z¦æ¾˜sÊ8º  ÷²wäo)üøB•´Ó\_dŒrð˜øsýT'OŸ…! éc#«¼’÷ŽZç¶±ÛçJ‘="75ôšI^;ÑÅžQŠ/#ÖdTB¥~Ïö‚ne+)*“ÿƒørû퉹ZJÔMéh̤,Kè4i“±àv7iù¯8¬<‡€Á…ã°ÇéšUJqV|§Á¡¨q³Æˆ¥|C.¤øöí§¡ìíþ‹oénÜ»¿º›ÞÏÇ“kxóázÖ£È.éò‹je?¦.XɲWê‹HxXP['Æõ!Õº|q|lêFjæŽÝmûrz÷ñ~|}3.Eù$ù*Õõ—NŸ?6 á“3û{ é÷gó|zbžOz w,Àë"–ôÙ´k:ø c2˜¥fitsh-0.9.2/man/fiarith.1.gz0000644000175000017500000000411212772016326014161 0ustar apalapal‹ÖèWfiarith.1½XÛnã¶}÷W°z‰ÚJâ™IÏ´iÐÜc`rAì ê -Ú&¢[EÊŽƒ~|×Þ¤l)9'ÅyécQ÷æâÚW&âüNÜÞÄÍÝùàòIŒ®Cq9øvñ+VÒˆ¹JU!­ŠÄd-*Îû‰LÅAøù0ü¶ÂÑ5ÖŸ< ð  UnU2Q…èïbb¦e¡íûy¡>‰ö~ø5ìÿB_Ã}Œ>u°èW³,êÈ­px-nOn.Z•ð¸'ÔRÆ¥´: žK”ÕS¡^ Ô¥Fd©Ð‰œ+#;ËÊX×ðéöî~8¶ÂSáU¶~Ïãn–[’ïg¿ ž ޶JÁŸÜâ^öW¯—•6/­8rÏp¦­9vâ¼ÕùÅðìap?ÜݶF %ò²È3£D6v¡È‹l^ÈD`h³êPJÔ÷«…ž.h…N­J‰z,f©•:­žÏÈøŽ*fe:µ—ƒÑ°¢£Í›+ad‚ýª:¡*åæˈàâE&y¬L &*ÎVb–`×Í‘B^¼†:K/ŸûŽ †‡C\±Ïijû#,:ºog§ãÞLuñwÂ{ëJ/Uåi±0%ü X 9ǼïÔy†ˆuª*¥áVç¸gé|£®©Þ}Ûl"E¤Àc¬H›±t–Ô¾ÒÏúiçoµÙDEZ~$°]ðÿb‚;ˆ›Jšì“HÛÀ¹T¤¾g5Õ3‹¬°õ/n¢&ãÁ˜ Nâg±£Û†Æ[sx®íÕ5»ÈÀŒ8âèà8HÉ÷¼úšáÄðÍD[Žjø›ÉÕTÏèegÜÛk­âÈÔE%V½áS§Å4 gg æå¸{dÖÇ­ë¬Ð¯J1Ç ŠH"§ÃÊ7ø8zD;Q2$„,Ðôü*()þÖˆÀoc¯ì¦L§DQ/‘æ¹FÔ€fM:r8ìÇ=q¨ÃjØÝþVÛ­§ÜË5Õ i§¦å¼Ž.’V:Ú`ãÖSë ú毲ה¤¦lRW6Ñ’¬Î [C îe9¦<>÷QPF¬“u]2Ïãõæ ­e”5 rV}UEF¦¢e*ªéRÍp”‘*ì/<«Â㾋Y‘%.ù¹Ã*š˜ ]º;Y"xå̾KÎYQe¿ï['Q¤kDõZÃrb 9ÝÎí¶nÊØê¯$"ÌÜ 5Øb (á”P€:òOSqWËŠKU|6bÀ²zª½ˆ9ºré]¥ªj­B¬™^„j8ž•agzÙÝðÙàB¦³&ESiô,øf—|MšÆb¢êh÷Ùaj(¦ ðl¹)±C1™ª—EbbAu)×µQéœ] kh»¦yCEÚóÆuQÃvˆô.õ“J Ä«"]ÁeðË™@ÚØpÌu¾iac|9êk²ó¸Ô³¥ÈôbYÃa2™¦Š¦ÉÜÅL­tÑÀfä’¶qTR U…:*õ‡Bä“ÝA‚P…€É•LÅQÆf²4‚H%a¤YË^ŒÀˆmdtÓç0VœbÔ ìÿg#óZ JÊ]•]¾E^drµš¢ }ì2¸I29„¡´µðQ¥´-ÖkÕíãð0bõž!?„«g‹“éÌ„¹: 1-žØ]ð¦i1{R{Š—j¦çd.…âùÜHØ€jr¸"ÑèÔ*(ÔäÈÀ{;f»U»@ZNÎò±¡’&‚v[N #”¦°æÉм¢Âb6ŸÎ7ôc´H×+j_% ‰ÿWhµ²-Üó>,: ¿Ù ûÜj¯[Í tìUü\=RÓ 9Ê=Öá³H( ¯º=Öz+ p笥à ÷ ä| ç²Ië(E¡AN€:¥vfäë±)š—(£+X4uIÛ«õz‘fèŒÒ<Ú`meªj”ga?¹"m¦˜iŸ!Ïñ µš"5Áh8bý.(8[hœL· “¢’>mrþ‰ÅGr íÈTEð‰·5ðˆŒ|÷´ÉÀzÄ¿"ñoÀ *ZíÔ&³uQÙ~#mRæ\ Ç×WžDQs3n…m ¬uba6%–“Z5\6tRYi£Ñ)‡-‰–%5tÊxÂ-úEêºUN[¤(a¦LåÚlثӯS)(‚ØM¡6A*rÓ(nÐ;õý ±ŒD“£Þ£ÅÔÊÝvuGàW(¼`l%Dzò†Ã|ÞbîúãÝøü Ì Ö.*kCÉûJUäÄLa:•AY0ÜÜDZ×S£ž°2 ²!%†})ñBn™77@×\zаA'ãË+Й×ÏhV¼k*=ª,«E“÷£äü¹®è¤y÷›’ÀNØŽÝñ6Ï }Q´=‰“Œ}ÓúG¦E‹J­¡¡CìÀ¼]O$ÕŠ ðœõLáž3PtÈŒJýÙ(i®iH¼WdHâú>,Çÿo>©G³°nÚy|Hn¶Næi™,78ÒVÓ­Þ|Áb{¶}É¡Ýñ6S2·§wE‚Ù£?5ƒ}Y ù(è×ÐãO­Ò5ÝœÐÆƒ[&®!¡õdyªæ¬za¿~Ñ{)ªÕé‰Ñ‹Lž¡Š”eøÊÿû×Áo4×Í¡L&B–6˜R¸><£orÜI%Od…s¸-;mYó\HVEãZ;޼8#ÂÄ¥˜ì(¬|Gï&Äj×g#WòñÑy„Rø4¸O¡’LxÄ;?¿ðµß,`à+ÒÑÏ[[ËígS'°s0ya´ûü°LÖà™³‡…µ9\ü°fg?ŸÒ<ȼ—`u¶QÞÊjðÅP‚Ø—@I—€>ð ?¯X ÖKœ0¶M6 pèMn{Û>¹ª{3EUõ¶Ù(;5éЛ½ÖÂf}Û¾ âHQ¤u šŸŠ&%³¯CSò,,÷ TÏPîçÓ“¿Ÿ}W0CÒt×¹ª²Pìh”ö£Ì×ùé þœ1"ñ(Ÿº;aßQá{}ãÚ×ÊÚ÷!*Þ¢à€ó™ »Ê¨Þoƒ-#ñ sQ³ÝœÆÿºH"’N¶§'íã&Ãý7W{²Ã–ÒÉï®ì•©7:z©sïJÃoÜF¨Kûñá«l¥¨YZ?rÒãµfå¨õ ©ØiIç´¢{žÌéÉù&Ó‚øÉäÊ™ìµGk9³³VØe-y<à‰ûñ›ˆ:fIyÅ[r6c"¾ð'¥¶·œnÓF¶(ÑNÀ^pú.了\TŠÎ‡ðÇ;÷u-ˆ¤Áⶉ»K mÜIU¶BÞFâàm(¯[ÄÀß(2ñ™äm·ÛºÌµ,éô„CrpvlýÃÑÙqǃ ;Í—; N‚(Ús}ïNŨIêI&XIYW)¢ØT%ì¯Ì24^‡Þƒ·ÀŽNYäm3'bÎ…ã2—üþÞ^žãÏíååù9Y{KÏôv~N//¯yˆH ‚<¼ ^Žžì4¢GN§£§wý!ÚãèÉ-ëFûÆõd×:‹Ž‰¦ç áHç ݯ¹»5žìŽ6-S¤qÀIü³¡V\¾¶òÚÛÏÎw‹}~˜f6@éÒ×íÀœÔ¤Ò,‘密!bÜ^ƒx<\5%¡´DɬaçÓ‹S÷–£ÊFbÌà8fuj:ŽRFOÁoÛŸÄgl°"ædÝçŽ|ã\A¡ŸqZÆ 'vºÐéÕWŽˆ3u¥göz^FšîL¶Ö*Mèn†ÒÈ=-nCÓù\ÓýnEVâÌÒiÔöËMpÙ?þÔJ9K:u»—’~½Rbš‚ÉÐom`}ukû‹Ñðöãøæönt})ο\N†`³tdÓfÁ¿lHìû‹ùVÌuœ«šX©gí˺._½šƒg.éÛ++ñâfüõvtùùnpQ”k.iâ~gVˆƒ÷ïQy÷÷ùïëû=ü}GÏûô|ðæb,Á`ÍÔÄ[þGÿÒÔfitsh-0.9.2/man/lfit.1.gz0000644000175000017500000001715312772016330013475 0ustar apalapal‹ØèWlfit.1Í=ksÛF’ßõ+æ¸ue1¡([Éæ.>YuŽüˆj-Ùe9û(Ë[ ’C0@suÿýú1p@ÉN¶n¿Ø&0˜éééw÷´ÇWõâ­ºxûA¿}qöêoêÃg—êÕÙ›—ÿ¦ÔY£n3£ºÔuÖ虚lÔRë£UVª'ão¿;ÞøQ½yuöA ž ÔàR¯½šèZ=~ò<(æy£þcü½Ú?züøûñã?Žþ8„ç?sZ­`ª™ì/TÏÏ_îÑø«»h¡Öm½®ŒVú&+ڬɫRÁªÖ‹ZÃ?³bcr£šª*h¢Ë¿]¼}wyv¹7þAá|{¯ægW£•n–ÕLUsÿÉÕáÕüý'ů«5ÎîžÑ£ã¼\·Í‰¢g<ê ©ƒƒªmà…:æ¿OøZûÅËËÓ÷gï>œ½½Øû°Ôj]W‹:[© ÿPf¦L[ÈŠªÔjÊPE?fu~£KÚ‡ši“/JÀù¼ªÕ¤j–*/ÀÈ´1„‚IÖL—8ÿgY“dÄH«³†æå4_z¤Ù*Û¨º-a~ÕÜVjUÁÒcõ*¯M3r`›v½®êƨ²]éºjMòÁpˬQS ‘‰V-‚ÖTÊè¬pq7ƒ‰6‚yjöeðXpéBÍÛrJ'Uõ 褩ì;„›Î„w»»ÌaÒ¬ÖO¸ª«•B´Â*«ªvcçy¡i¶&›´Q2À±ŽÕ¥žVål$Ngš­³I¡qIšR¬†(]ë?5ê&«sÄüÕ,a ùTUkd‚¸È¦3k=Íç9óBø¨Çê‡ÌäÓ¬(ðŽ"0hø‘Ù¥yMv‘s ëò9®áHÚÀ¿úAbòËÝ´ÀMâÔÜaíã¶$¦$FhU€%ðÝ0 ›"_,áx—Y¹Ð†p_j=Ó4 .‘t^ÞTS˶õˆ§lÌpLœò–˜˜ôòR ^[v·Lø$‡w{Wó®–À[#Eÿ„ ~à÷ÞkØœñB6½ÊêÊ&ÀÛ@ØIÇaΫ྅Ÿ.žžßùE2Àe“ ál@¸@¨÷Î~›_ç}³Ó;ñt¥gy¶ëƒ0àsaÂ#9w_ÍgMç P ”kºGf /ßðñÆT+­ìSX‘—¡÷ÇaeM´¶'e¹î¦ç•{hÁòoàoÃä}È ¾íáG”—m^ÀÜ€’ÀDV®>Iªï2äfïÈÐ&lyR8Y¹!$ߤp ô?fBG•¨q„ã¢TÒÿMt:°?ÜgꨎƒÕ\Éq·vìáÄi<µÃMÀ¥ì[Ò¿ª¿ É?"„_8²XeÓº2ŒÚÛÜ&‚'C´,ƒú)‡´ÇlH·†]QeøFßr‘2a m¡å³h þ×@4lmÍi>0ÃØ!Àû¤ŽX&©? mÆOš´b.,æNÈ"Ã[ø½AÐw×ö$æ„=”ê@Êÿ-·…U•I+£"R³|>×5‰%”аºÕV8íÖ»¥?¬¼íDN̶ ØÄÄiŽ˜0d`£òD·x[ ½Nì‰\ɳd­0s?Ç&V‹H8¤*#áù¯Kp)œÞOvá¸* 4‡ è¬la;Ù»úD¼@·¿RìçZâBÐ`wÀãŒ>2ƒÞûˆoHjõ±Ñ;lQOñÁï“¶h¿ð—¬âüÖ“`b|"3w8Ö²“6«óŠME\=ˆÜgË~]-¬9ŒÏØ'BEOSmð3âªÝûT×ä½{·d ¾ÇÀ {>ÁÝÚb}€uÛÜ,µ¥}ïn€éXNIˆLšØŸL÷0{äò9÷š8,fu 69†BLù¨Ø š@ãæMú{Kk]^†-yëíK ÃðFµB" Q—ºeD'h–î:ηrß%CQðÝïÇ‚ÿïÙq)˜·m‡È—Üõ&nEÑñŒQÇ ÊÂ|ž£a6-PŒâôR¡3à@óK Ô8}óærh×OÙ2jÅöîn^éºyÀ·dŸtô¤£ˆLj+`­µCk¾u§ï)4¢×Ôä &–’Ž+P XƒÍÆZ¼ß}3´áÒ9èV¯P`Ð8JTÍfÍL¾+ jEX¶nÃð,ñŠŸª­)d¬‰"7/1k(€ºÿæüâf#Pe|òHöç£ë×wS½Þ´µ>RsöKºäbj!²bc‰ Î×FU¶?Æ\‘󺃺€µXA¦qÑœëäy–¨áõŽÃ¨ å?Â!‚"ÎüB}û•‘P€uœqéÐ}"VÎûK$HðXPBJV†ßVìþ&Q¸%»I\ïƒÒ‘Ö›à5eÏ?¯œ"ˆ8Ð&çàž ¿Zæ:yz†lNFðð#é`Ž&m=ð{4p6Æø°(ãäDOý6bð¢øÐéçHªàÎ1™i5¸ !›üWoñ9LÃ`É“Îäá§ñ!¤ñ³™hAÅ\^j1¿€KÎy_Wç ]Š£áß°é*HöW„k@É+4VYSçwR’¦…«ö¾­Ó,¸€fÄ3‚+(üj¦}^Dàuu£N—(ÎANÀYfuQ©ýóÓóÓdd ÅŠ3•êIÞÔ0fÒ­í8±„=/òdÕÕ-È^àlòÁïS„V¥? ÕvÅû±îó?°\s( vÅMž}©ŽùBnáò—{Ö3M"”™Ó#ÎwˆÂâ€,\—­êZ³²xµ€XàÚáC®mOÚ êˆ<ž$¼o¤ƒ ¹h•~£†Åö €-SEPøŸb _F)Yøy„ÿÞP {*Ù€ýÛ2ÀÃ`R·À}ðkª@ùùßb) ëZ1O‡ê4ˆ‚& ’󸵨óÙ}¤{(4”>#ÙÆö¤© > m:æ <ÿdu,R»M¥žèzÑÅæa\‰%-åÌ[Ýø‚¯ÝºàZ›½Æ)-½<<±›F¯á¯UvwòÉŠbòàÉSƒ‹ÜÙnv‘Ì“k°©È;mÝaëüôTJcéê52Ê) ÇÚr!îÞc\|ýÄ%ÀÀd#{]è0Ö‡b^ˆ4¯YvPIíì ŸëØÈ„ÓмW ÷N‹væH”Њk7ndóP†Hrfà[oËYV6Òn~) H¯¦úaºdK¤Q¥Ì¦„×h2R´3¡§;Ðu EÊF›&ç„Úy~úrhãÔvvIVœ¢Ìb}J7mdáöCYÆÑ,Ú1œ2b{A;Í  ¡/£’a+®„²ûu¥P ãv,F³Ë´öÀÎr€K¸Xoˆ…½ Ú/£ÔwëD¡"0««–LIªb"žÙžÙç™"èr ø¯5MïÊ äw$âT÷Ã#2Yp¤>D/Ш‡É®q9Š®gÓ)좑ñuJ¹2JÀ,ÏÙ· v­ß#M™ËIoÓ­›k’=MÝ®B®ÅÍ8䯒CîVýÖVFÿTÏ1±H²ÓUÞØúm0/ÇöÿzŒ±ì窎¼¯‰nnµ.e(Ñjm8EüÒG¸2+ Xt:ÇêÉ!Í V\iˆŠb !eûöÛµG<™c_{'L¸ˆ¢Ò*5¦­ `º>ÖX}s¨þlËúL €¯»ÔÓkÞ¨]]ÇÅr€|g¹Ù¿2~oÏbŠghe,z¶°š©q¶Ð,·€œm(d ¨˜° ä0ê:È~ž¶©œÕ† ].š%© ›úO §Õ·nhpÃPᨭ£“rÿyofFª¶_È*1>mA¯ÎΟuã«cØy+ÌÊyðÓ:óS$M%à±>™U0Æ8,5êrFjösk¼ØˈBÂ:›Åþc¢Vê–š Ù¬a*ÒIn|(ÈEÅo“hi?ÌЖ9Œ¨2t3%ZXKË”ôËíœqt„ÒÈÁª.T®¥^P¸Gº(Sô/mèA× vE£o5–©*ÇzlÅ¿0Õ¶&$øŒËÖM³z&E Fö­Ü"¯C{äÞ·IeU‹ý•' ¡UÓ˺3oÙmyQ.ýC`Jlì[î†/2¤Êâ’|ç€ÙUešnA„$J)êA¿qþ•¤ÑvÊ0æ<“»\FGSôµ³±Á•(æ°#LtœŒ&ŸÄ:ÒD&tæÌ_Öãar™  !†`58¤ŸôŸøö4FîXÌÞOÖsç”Ù;’XPÙÿÖ7˜ÙÄ™Ÿ×éåd‚ÏJ%H¾Ç2´gV²7µÞä×>>äê)œ¥›DF¨ÏH¥0‡½ÑdëŽþžÙBÂæ§F!œêÑ&s‚÷Gî…ùü»£’܅ݨL&÷îCåoI\ê0±ñ/†¯ÞìË6ËŒ\~Y¬F?á R"$=BÆ&[ƒ0¾³¥Hõƒ…´{_:¡§Î×P˜Ty 5ˆ“¥¾ù?…Ⱦ€ìù ALYÚ \-”PáäœØ“OŽqÏõCS1Ï~Žã!µ½s”E~B"ÒϘ^MG@à%MÑG"LsP€U\ä@á ¶ ¼D*|»,ó_ZýP¿+$üyXQVú»DÎAe¿Dî*¸άMÂv‰Ž;›%¨09è"„Õ â #o0…—-h$šÅ@"ÕjEÞ*#)jïl[.¦©DUuJˆ b¼­ìG~nÒü#ãÒÔîÉ =Àu……¯pS.SK ZsÝ—¸wÒ1òïù^z+ËI¸à¥mCU£\Û&b =[ø~Vúøs4 !æðÁ k¬Þ–"z»ÌJ)!f‘Eî0&(xÄá¯ã~žƒlWÓå:wôèZãárw?!0›ë|Ý¥r"ÚN(%¦¾.åâ,kÇ:E¶šÌ2¾†ÉÝxƒrÀ£Äýʇ•‡X‘È¥³¿ÈŸe(ÚÎí lMUáJyãnh=Ãøý8ü>Ù»hé1^EñOÕ¬­÷üù³)–KèÙÞ©ï¹GRì9Ù’Žrí[mfU3ØD‰i› Óuû~öuÑ6ŸÜ£áƒWäuùd‰×ø £ ‹êèké+d³lüë?sx~Ë&·8-,(.‹ÅÕWòQrˆȳX¹ÍK®ÏŽùo '{ ?ˆ4å£×=q*GÆðóeßG| ØÞæ£ÛŽÆ(Æ^43ìûèñÈêOô&ùþª•ƒ¶~@ú·ÍfÍâˆ\0õ òm­Ì§"ZØØý O¸Çl$O؉-›Å oO>ލÚúƒðäE KŒÔþýF<Ø7p:ÁúJAT ¦ÌÞa¬fdH9¶Ì?´º§OÉ(!Ëð‘ õ`"p¦¯£û­öÜ6ž-j;’¼çj¤—²¸sÄ– <¡Øû}±HQpÜ-ç@4ÚE}5»¼çõQ¨$Blª8&´Ê®m€F¼m$Àùòºš ~æ´QaUs°9lhåó!Æ`îj’/ÚªMܾp…éÅF^noéåà­*ž‡Šþw\`Ýá~*5Ⱦš|u÷uöÕ´2ûwï'_áã?¦_Ýýýh€†[= ìg£ép@HìOèßAë¹b ¦D¶|yÀø9}4FY ›bû•LB¯w¯vï“»IÄ(‘™¾LÝf5Åos¤Ö¦[)f—÷?i6q‘ÌUUR=¤O„ow’r\7µv®£Z  Ðt:xÓ¾Àã4¼H3ÑüŒ¶st1kfÛz’¹«âê˜SuH¹â$Ä·†]ë ÈN9Ørøóàö=7.÷Ç¡rŸ$]Hv\"!9V/»—‚€ït][úŽ è)¬É%c2#Š=VÒ×2©“Ìá½”pÓÞŒ»°A—@ÜÕ+gC©~¤ï†«º«+jÁÞf#MÜ­¡€s›Qxž¼T=wéûNšRfL,§õŒ£Âm… u=;Ù»Ôöv/…ÐùÏú¾6ÞØx­osÖ˜Ð3ê1âÛy„rŠÈIÞ Õ!g ŒÈ YË2‡9û•=d˜ÜrVHpÊÑ#¬fí4§jp/TdîŽñ9ø6ôÎ&‹óoB|“ëÃõÝ:¥¡KÆÖÇà.}êúœ|±Åè:7G~¢@8À¾Šï½`ª¶ž’Т±hÔáLß~l?ñ$ð|c *_P^‚ñq‹ºáüù)òâ—0hªáH¨« Qª?dì×yɽ}’ »*d‰h!K¢ê¯¶àq„Å*#ÌÇ0}ù †OäXú*dsqò¶ônKD?âKoÝÝ0 Eæ¿ |‚µÕtšÔx ˆ/Ñ‹òîÁ´²”Jõ°ÖB0‚¯k•õ¢«b›Ò° ]¼ º9–eq+œ®Àav7 pyù®LSäÈ (¬x))êH.ä J2ûµþY»–!(†¸?Éû½÷îK(gèc‚ŒÌMîÑTã½›œONÐKÔq!œ-ë „ãz²wžÝå«v¥RoÝân³S·ûéfê s¶é˶`APSF1XkµÎŒ¯:Ôõ¥‡¯[rHÈ8ü¹ÓÆëÎ5 àŽ²º:øÄ9EÃë{/‚Y¿“ÚF§«^(·¨Tœuôo»C·´£OqQ׿V9Û<ÉjÓ×÷än+{G(½þ­Eèh|¥`C¡”SMó¬ µErËì§“ùùåà»»¬¸œ½{9EZƒ ÉŽ@×Ôd }?MÆ[÷¾k•‹ê#WGLVB³Œ*ãÍÉM8J¶ Ï:©n8ßÒ=‚Ûl#iÝq†)«HŠëdì©cq›œ\:pæ¢áâz0Æð9׌â,~Þû[¬Ð#Ù„£C”}—Ú; â‡@6uÛq$j:>Q§©ÍƒÜ„Ó­IJ¾Nu«5Àç _‡¹j#µF½ýœéoÃô–eSóÛW˜Yø\E_rs›oM”GL°=[ÄÞ˜—Æ=‚Fª³#ß‚M\—òjÙ7ðþ—d¥&¦Q7&ý”¡ ‚ÿyv|ò¿òõ·|k€œ=W°×°lQºˆ²1íì¿´5mâ3ّ¹mÒ‘pÎñþ\èÏxE{Þ%—æ ã-J…£áu”_+0ï·¶/ËÅ–‚é®ÌLò’Zà…6> ¹ïìq´Ê¦‚]gì8dåSõèäÑȽ±ù_z| ÝH¬ˆùÅ}SáÏq}ަfáÝñ³G òm·r°}B‡†­þSì×x/3í˜:æÙEƒÜúÁ÷ñ·f’3J¯÷Ö_xês#ÏKNU¹N)°0U…BK{áÂu§ —”ûo[d¶‚JôÔäÈLÌ-*ðÇåOŸ \%!ÔÃOÉLQ[/Å] E2 AÆ «»õí»îP?ÒŸSç…9Ø ÖwbòqC)}ÒݘÂýìÞ¦ß?EbÃgÇAõFši;tì’ܪ†°+*!BHsŸŽ“€¾wÔÐ]lªµã÷TËAD´èMÕmEM£âÑñ zÚÔÕS¶«’º…bRÄçqc+¯Üýݴį¨ý¬-ô=ªdû(+2ú#{eTm/;ÍöÐמp,?¨ýÄ)kqë.» í5\Mê‹tƒ­Òxd%ɧ§Ó6Kœ ð -é²M5AGrhÕ¾Ÿ‘ñ³ò†í¢¨&€a¶‘9»ÜÏU×î8kìÙvO ó‹Ž%vaë,ò7ᢋmkàny÷;Yà .~ßÀ¶ ÙËÔÔy¼XÕ‹åõÌGhmwKÜ$‚‚ÔgÛÌâGP鈶TD=kÃ&1é΋la¤¸•ôPüo……‡QË.tø“õ¥,‚Ãýylàƒv§2¯aÿ(TØ‘r71ÙÀÐ7Y[DN³ßÅþV`1QõŸÈ›… ·-ìü‘µ4¦¬½ÝOS=rך©95å:š&!à—”Î¸>˾ºûz2wÓlG0þÜo/zb—¤t³ºAfó*“§ª2Ý•†Þ B"œsct1³6½£u1¸ˆè£{l‘¼ø5åɾAq›Éçã¹¶“áòŸk$oÞå[Žl„>*fö]’ä4ë:äÚfrSÑŽ„«LBc#“¾ H—sžð­=Åý›âÄ{áâN˜Ìý ;K#+ðJK§-¸„1k»Ñ44¶"ª]”dQ­„T¯·w™>Tl‘L±æ ?pîêÉèUÀèbÐÛ<@¶†òRÎk±û·K—Cóä ü‘Xð¢ÛLµªóEÎ…ìÔçX`Ý‹s»zܾØù“È9‰Ç!ÁÝŽþô}åiaùWÑ% RQz]Y{_9ýûÊßõϹƒ}3w¡ÙØ Á®ûLeáOö¿vj>ìub †r4þn¡ö¿sD„44Ïm­Íð[yè[ÿÛ€9%”/>IAÖI–ªØkMÚJ÷^¨¾3WûßDl–€j›é”FnÌGó)yöÛaËd›fbØ­6[\¼íó!¶l)A´[WÂ~\®£7w5êÜ®á.Å^K …J³^¯3Ÿn½¯‘Jz8Q“4‘IÚxM‹A#'jú{¿fÁn³ùžúǤ?<ŒnÃÏ%ÝÙªsM·þ¿ƒ]¬“î È©•ŸYí{0'µÈôÛúœ½ Í“•ý½3ñá+`Õ\hÂèN<;·¤T(Â"íÞ¸©•5s‚º†“™·E7º·•Ñ‘wGQ<ѵù[[7n-ÅPZ!®-7n lŽ„!¨¨c•º/;åCŠÉÌ™KHžþ9uœYûçƒ[G^Åû>ˆ`Û%¬SYÙÝÉÏý³Ï)KSV#z%Ì—®KÇPQöͽ"Ôsû.&¾÷?aXnBLº†‚ ¨J‘D˜Àª”Àxyʱ¥MB‡=îýá‚Töœ-nZÇe®ïE|Às+BÏŽ'Êí¿í‚;ºwlþ‡ï_¾{ûþÃÙÅkõÃO¯/{ï)kHYPkêc°&‹ÿ6¿Vó|\êæDÔã-›fýôð0K|wÈ3ž¾}÷·÷g¯ü°wZ­75Ýé¾ÚŸVêÉ÷ß7RGÑŸß^ÀŸÿIÿþþ¿Ô;tbŸ—³“…E÷þâì›mfitsh-0.9.2/man/ficalib.1.gz0000644000175000017500000000401512772016326014126 0ustar apalapal‹ÖèWficalib.1•X[oÛ8~ׯ8ë—Ø…­\¶[l»‰1MÒ¤š8ˆÓÅãJK´Í‰,jE*±‹þøý)ÉR.î΃mŠ<üÎý"‡Óéz|GWãóÑÅ7ºû<šÐÅè˧¿,= C ™Ê\XÓlCK™dG+‘Òaøö]ø6 »Ϡ?ûøetJÃu&2³r5“9¾ÃÆ\E"Q3:ßS_áÑo|`õ÷¾Ÿé`cÓ ÂÉgºþxõ)¨.N”É|®ó•Jô r¥ Cî r)’±23„…]JRiVXR+±ÆM¾]o&£IžR‰ü>¦}ñu3ÝŸÎoÿ ¿7P?qì~̰}®q® ëüoEḚœÝŽnîFãëàâdEži#IÏ!2”åz‘‹ai5Åú¯)ÔÇS”1[b¥PÍ&éO­Rlö½»°­dn"x*Òy.#§hŸf …©+×YHVá*¨÷(ù=™bfsáÈÝ<V“IÜ ªc§%ì:™PçÒ…IB¥M?À‘w7Át~:,aœ>¹%Ax.Õƒ¬‚+[¸?ߘÁ¤NëÈ%*•h¸Åœ.j¸6¼?«™Š¥ JÍXvÅ/ÑÕ½z Ý5vW2Vb×…-Á_• ê6qÛ’“½ Â&Ïjk`–:·Í¿Ñ¸S c4 ÜGÏÆE@íŽ2l¼[&p1Š:g‚/¥VÍè¥n‘qÔ3`*×¶Ô²×@ÕMTŸ^¶Ê´·LÁÿ8oçò1WVÖ)rˆùìý~<Ïõjøóc«‡{Á­'tÀ%Ç9œFL'FÈ —‹%ï¼À™Éd¤2®`ò®ÈÅJ¦¶®æQÙh׿C™È-­ héaË“.ÐjA®ÖÔ}ÓÃe$#îç2KD´e sµP)Ò¨– [(swê5ò<˜y-›K‰™$¸ñ(Lk$«*8Ó,÷!š‰œº®Ø-]ôÁ€ þÿz=ú”ÄpÚS”K¤$"-S™4=ç•\âD’T¼ö‘µªxK”÷ ˜Àpù’B‘ÿÚúGѽGö< ä¨@­GÄ: z!¼•ëý¹MϺ~U¦á Uª-Ú«ÊlS €>´ªëµc|@Ì|,v«0­[¾¼Ô¬ÃF3BlöÔT(»¤¯1åÃ0˜x#á‹0;à¥~J]#!Qb4uÆÏÏ9 ¼a:Ð!ѽVíö œYõCžtÍzØ?6›a¯ß=.»»)¡±†apå·]Ùƒ³2èÅÆ™t+nCª’Ü4õÙ-ÖÕó²>X sï,Ä©1 FÎæ¼é b&ÒÓˆc^6 s÷ôe\H1ðTâðy1 ®Ü¶ŸU¼¢]d¹H7M9Ïwàñ$ãðxQã¹ùæU¼‹x<yý±¨ñ£Ñ«¨¦Õ~…-|0:°D>ȱVï’Ûi9RÜó÷Ò ?–­v^êG–±È0$??…<ÜçoÔZ&û¨!17ôÎ,Ñš§éŪ ÖÛEfnäÄåÅ0¸æ{HR~Âèš²%¯£ –8YR¼â|‚‚¸…pݤ@à,ç7£Bå )^Br“y6ŽaZåYu:Øf«u®Q¡1^(8n–m$_\ä\ОNµ-ØTï€N÷,Ïç°àëL¸20ó 6Jôlæ¬PBqñÄ\£x±lUy’eUåkìS<-Ún$ Ï®·dìG˜,³O ™»ïL¾>~8Þð×úˆWGÃà¹Ì)j³h ksµb)ïð[%/Ü2ßu‡¬îyíìîÛÔå\‰mW@ÖyÁ/ Nö•tÕ—Ÿ`KñP6€ztaÂÂÏã­ÀGeÉÆ§,Ü®‚Wåf«>UÃÎc0œéH[€±°ÂÁ0ëaP9Æ{gåHÞ.° „Y3•fÊâfYèx U1 !~b¼CßM*Ñüa­ž‹ˆÝ¥ 6ôÉKþ¯ooi2~Íðî^?s-‚7žôº•ŽÑÿ|þÒ6}ÝÅíãîk.ÕOªZ0v‰ß¢¯“žº?d®?ðhÆsb-H_!ÍÉ1× Âý¿ÀÝ¿>p€¹ü“mƒ\©¡aÒDa]j­+˜È4LR` X)¨Hyd¸±q,*¸«ÑûÛé‡+õƒG÷áŒ\È$¿d¬4|È9rËKŒ¤5y¢*áѦK^å”°æ_ ÷Û þ]“\ ,bÔ*7»ší´^g¥·ÏL'ÇÛ!—ŸQ.8ݦ2åf…à¥=›”NžÏ´,ÞËvÁÆnk×U¶÷‹‚¹%ƒ= æž/T®¨üZ¨ÒË@ª‡»ÞÖ÷[ »ðy «_‰éP³u×þÏŸüSÜØ.æ<tšseÇÿSÒ¹ýt3¾½]_Òé×ËI‘áUóñÂý t,2‘üf~è¹ Si‡}ªG¸¥µÙ‡ý}ž¼–|¶ïÏÆ7ßnG—Ÿï‚3mÜh@Ón¤éðýûw}::88rßo§|ÿ“ׇ¼>üÇ¿èF$}ú˜Æ9$Ê:øèPèfitsh-0.9.2/man/fiign.1.gz0000644000175000017500000000334712772016327013641 0ustar apalapal‹×èWfiign.1•WÛnÛF}×WLùdc§i膑»# ¶ Kyª]‘+iŠËî’väã{fvIQ¾´è‹DîÎ}Î\˜.z?¥«éœ.§ï'¿ÐüÓdF'¿ø‰hRÓò´Ö¥vªÖ9-w´ÑEõ|«J:I_¼L_¤ƒtþ ô“‹+JNJfºªõv©=?>y‰ƒ•1ë’ŽÓWšŽð›>Íé1ž~âþ³í;»…ÌÜ'ƒtö‰®Þ\~¾Å˜ {7.ô­.$¦j U[’]áÝõ¤¼·™ûj Sæ32[µÖ^d;\M¯g“Ù }K"rðÇb5YŒlÅRÀ]æd+ö_Ï«›?)œ™²jê󃳱ý1ۦƅÿH ÚÞ˜½»™\Ï'Ó«Á¤¤z£)³e­¿ÕlïÞ6ÊU­¨r6ÓÞ›r=¢DœIH9M0‡*ó ÷|ÛêZ-ÆÌ7"§+§½.k°Š_ƒ†UðËÚÜê2H V„ü£päÙ"oríBÀ–à¶[½±w”,U,Ø*÷×w¦Þ°H¯c¬ âîÀÊŒú[V49´:j@`Ëb2ÕH†òƱ}«ÆA„ëy›Ò¼'3˜´V+.˜ÒÔFOúåéH§ÓzËÎj@vck¶ þD’ÝmL¶¡\ûÌ™¥ö"1×µÎjšÚëb%`(ÁLÈͭɶ"3ë•ÉXh¦ ³ x¡•S[í‡#>ß{STžÃ’ÉP³ôúïrà”®|ëÔ>*Ñ%¯ê&T[kyœi—Ä÷¡DªÆUÖw±ùK°ý‹[Ã&2žSÄ#Å´ˆ%¤2ÖÆw½´¦ô¦¨7¶YK²{値†XH=òj·¸AëÑEâ0V$k{Èâœ3ãXl¢S¥_Y·…·ˆ`íÌ#aëC­æ^û8c‡Wq ¼hàºv;¤'^@e ½exbsa¹¥ gŠ]*u=•’F™Í(¹õD±…œ¢iͯ‹ÕÛÅxƒN0"yÄ Z%ÞˆKÛE¦­ÎíH-‘ÖØ!¤ùQaJÝ M÷2‘:[®;q‡âÃ]§D1¤•)4KóÒtþSúùjž’.w½SÙ¨cØü_›¸·\¶ÜĹUõ·Úyöu¶Gc¿±®îß„ƒO4†[ÅSh jøyŸŽˆžîƒÈPÀ¯àÙùàŠkQ(úÍžIzâl_\˜!ÿ*/Ž›{é(·Ã»ò=õ{ÂaÚƒ-ZX˜,Œ}n:€ø Äè*ÖiÚýÆps4/¹$c÷•â*9 -ݪ¢Ñ}˜­•©×êiñò¡¬ïÉú®}TŽ 8˜Ls©–™ƒÁÌXCª3Ý-\…Ös¸aÜ‹qOàåCœ´¢³;v‘-©„ÔÌ.Æü󘨧BõU¨ª*v{ëßðkר:SŸLª1[t„¸@ ¶—¾²)ŠŽÈâxÑ–¾\¯TSÔ2æT¹#+Ó:Ä•;?FcØXóCÛ4Šdس{ÐMöD"y:LQŸ JÑ¢ºo2±aÃvºêoUa2SËøH‡Í°› täµ£ö©÷B—´rùïOà~mx14RH둹z>˜uG$'=Ÿgó/ϼ*l:{•7ÏNÕÛ—Ê›{3A«¯ü»ÆœYoº_¼´wÚ-ÆM9o‘GÍV9w¾Ü8žà¶ŒP±ŽwžnÕN–…µ[˜š`}q¦’‚ A\àIì©ýX-Æá{¶Â÷цï¦×_n&Ÿæ(Üj'í‡G™¥“W¯^Žðåü\~_,Æøý•ŸOŽùùä—ßèš?Eß”¹üî«üŠºÄR‘fitsh-0.9.2/man/firandom.1.gz0000644000175000017500000000654612772016327014350 0ustar apalapal‹×èWfirandom.1­ZmsÛ6þÎ_Ó—“ïdÉvÚÎ5çjšÄN¢iýr–3×LÝ›B$$¡& – -«Óû ^'Ó|p(X,»Ï>»äð®'ήÄåÕ­¸¸:›¼ý(nßO¦âíäÇó¿ 1©ÄJZ±P¹*e¥1[‹¥J‹“LæâxøÕ7ï†Ñðö=Œ¿yuyvu!zÇ=Ñ›ª¢RÙL•âäèø¸1ץ̓áœá‘è ¿ž|‡GpõâÆ|°0þÉ@tb{Ñpú^\¾º8š¹w‡"VȲÒsk™ 3ûMÅ•Hµ­à~ž«³:%uu&Ê’¬éÇË«ëéd _ /2úùn>¹˜¢Ò&·w£»ùÍ/‚ïš?M]u%Nùÿ1 igçÓ77“ëÛÉÕet»T"“:E]Æ*aæ¢Zj+ŠÒ,J™ ¸¬L£ûSªL>îK[•&7™Žezàv3$®hmØÍt*zïH4ˆã¼ëÝ^Gwó×w‡KPy è~ÀÑÁïè~PþTSak°y¹rûÍ•ˆù@¯\y¡ÃVæÝajòE#®+žŸ5‹H‘¨JêT%´K´Í'¥¯ô½Þ'žw3•hùÔ„vÀçê$àH/ül17e&«Žžª´00\Óß:´KSVá¾ÌqÊX“)á ^·Çáühȇý¦T0 _ìó£ðôÓP| ¿Å)^Œ£i¡bœ/y³°p(f(Э{xÙ…„åUñ »¨S€ðbaUk:øƒ0æ*¹°±Zêx)b€ ¥a%Oyi­ÀúqŠƒq—èð¢Tì $ÕyФ©Y1ÖàôÇ¢T–¬3SÕJ©\ØßkY*1+e|¯ púía·7¤óž%uc"ŠDT%IPUCöÅM„L­Á#Ç;x ¸·-}Ù,ÛÛXJâD«óJ>âÔÓYj9KÕø»S?F£(л" üÐ’‰fÊ­Š;‡­¼¤œGó:MÅJ'ÕR€y–2Ð,r]Õ‰ý·ÿ}qÀ` W*mÐWæåò>ct•<Á ¾ëj½o,"À1Í^˜/Rõä`Y½h-¿c8kŒhXšz±L×âdøâkñAóHX%*­¤èim1hd用-óX|z’rÝË¢)qiì—‹™Fïd ®'”A”æuˆ<¼Êa³%\9øg+ò`ÿþ§ßh³ÿ;áížE}Ò*,ó”V?DÝ]=kÒc”#°¤ú˜ñDš)c6rGëuŒAVit"úµÅ b²L„—A>Ï;ø)’3kÒ$=G,ÍY‡Ê¬ÿBe>¶Ê||®2YÔ†Ô†›3dÐ(ÍÓúq߀ëëè ò†rù?ß6y#¯Z–J õ{­`mœªu +úz¨†b>R£b ì(Ý#NNGg£†b Â(kd¦Tm*KL\£'ldJŠ \‹ªÖA5"ªC¿ |Ð^üæd9ÓUI|¡d¹:Å ÄŽ³šI £Ú ÄU ™&¨T‘â s^ç1Ã7fcÅæNÙOÍ`©èÑ¢Ÿ)™:Ü@…:%"%ê\#†Ã9$î嬯Ìäx$ÄñŒg“^jz$²·Ô|!E÷Ý)+П7Æ©döP 7Ÿ”é‰~³mrÏ*“*Èùézç1`ø®ˆÉ«R9Àðº{ìÉ ÙÔ÷§æÀYÎI¶&tÚ0Àœ`|ãô#z »F¦ƒ‰ÂbÒuV9j “œ“ºô‡«pE—Äç;ü&Ü\‡61›Þà##a]‚£zqÍí o Åç6ä ´z=³c_„Çó9TÎÊ•tÔ™«kÄŸ^E iSÏâ7ƒ2>æ3tß6«¢Ñ6r§#®–h6ÕÑÁ&÷®?Ÿ«9Ý@pÚÄå9õ=gÕéÙáªøó¹«vcõÔzû8+W3![µ@v ï°ãÁ©]a…;Þ7hr—ã[›…‚® ýH¢ø$ù};¹zù!ÇQ ë,”•ÈJ²RËãèŠgÂ4• |檄. „eÞ¯YÖ=nî~-ú3œ#,DEK%h¿»ºaŒŽWKˆÌ§".í¡Óíq K~"/ù؆¾…œ)ãAñ’RxU=àý+ðµ5d>,ObF.ÝÄÕè¤m ž‚໽ˆ`­`[p´ÀÑ9ÏY¨œp¹Ñ¶‰§ÖV}“MûÒ23]£WIBÑ Ø81=„Ú-Þ?}7{ptÐsµƒœ#}ìj§_'ÜŠ¥©°4ô*5ŠæfûatÎ= vhJŸë F–€™nMfðtž™ì¦"Ì Ð.„ÍL±åþö“t†c@eâͰ;±s yÅ7Cô™„ç“Äæ/Ó†.;éOà`Ÿb<©:[¼h§"Ó€Él`ón›[v<$Rà)„xh¹î5 ‘Λê 'aÂr¼Â…1ÅŠm§ ƒÊÕ°.:_rr\G}B*áË”þ 뎻‡ C3Qyœ> ¶—š)_Ú[šnË÷+³=¹É·jÛ!ûÀ;YBoÐŽ£‹Éï…K¹ï7GB_‹ý+¦Dÿ¶ÈJ”(’å„ ¡ž‹R¦›Ü#ƒÃV`Y¦ᬔ«½MÅ–}s¯%°'ºÚä<¢;Ëê|Þ’R\°Ø7(V¬$Ô—¦BõíðèÎ0ˆÂ¥a:‹­‘Ý;LJïƒXQ$pSâpœa|KE0tŽ™#ït™VMó `(>CÍø¹SÔÌÜÃý`˜FQ4;à„RÍM©ÂE] ôŸzDÝ»»£dÛ9"^æÐÖ…g­ÌÛÐ}ÆÑd¾-?ÃÊ÷ÿ ;¾±‚Îç8 ö ¶[P§‚9‚ÜLôñÉë ÝpkJ“¤Ó(‚[œ†ábü§¬+Ñ+nß²EiøWÿ.ÿסxñ\Ñ+íÎJ½\PKÜšìLÀ\qœÎ?0u‰$B>±¦¢ÛÁŽ,ã%«°OŸŒ€ìjžˆŸ\D\—%ed©î)О‚nD°5_soí-ö]³ Ã@vH¶ •éçËöx~·ð¦×ÔÞ˜Ý6åu'uùªßÞîÐÔ¥·ç*…ï&†…_sÆPÎPñÍ/ 6{^×§Úз®¾ô]Ñr–ïŸ@™Ï°ÂþÉiö[ÍÏšÆHl ì‰pë0U’m¢ôïª_¶[·Ž}nV@$–Š:®ÄV+¤!xDÀ²"U;«ªÝmuG œœÝäÏ.5ŸÇÚ"ÀWT:Ç¢#N‡{_õ|ºiv€‰ ¿užâ[lPw³…ã”ùgzñFgqË Ô•©™Ì¶Û QºuûéH[|KVÊCXûþ§ùÚ*0±c}µÿ¶*–9î$e ÈOÂæ' ”ÇÖô­ 2ëßz„mOlFó.`JWïƒ5IÓ/âºÌˆ›·•1©ûZ«ws~}us;¹|'^x7íE7ªÀ¦ö¬^ 9•…L¿·ë檻eU/G£9œûŸX⛫ë7“wïo¡2-Ö%Eæ]?6âøÛo¿ˆ“££úûÕÝ!üý^áõñ×ÿ×2ˆW9ðx»µtô^jª(fitsh-0.9.2/man/ficombine.1.gz0000644000175000017500000000231012772016326014464 0ustar apalapal‹ÖèWficombine.1VÝSã6÷_±õË%3¶!”cÊ5dîx¦ù˜8÷ÀÔ}PbÙÑa[>IN€éß•d‡\éK²ÞßjWû¡ vájÓÙ&³«ðë,oþ†\ÿ*Ø -© Š&°z„ Í«“‚”0NÏ‚ÓÀ –·¨?žM.Ãé5¸܈VŠ+*àäxp†Œ”­y±b%…ãàzøœ|Ö²à©_û¨òM¢ú˜H× ¢[˜~™\;Ϧ±–de½‚K© ?jZªüѲÅCf(ëIðXA2* Xt7Í£0r‚KØc:Æi{¼RŒ—2>ŠÓÅ_`XCVVµjF`DVÙçû>¯•íÿÈZ?W×ÑxΗálê,7ªZT\R}µa*Á3A @RqhcS¨Ùõ½SÖ¤ÀöDe_[`lcN­bK jaˆŽM©Võž•‰öìî“ãBÊ…ugy°á;ŠR8rá­-çNœ^Æþóá!ñK¿¶¥m5å k¼kñd…I4'ZÛÛ‡\g¤ ž1c?çe¶‡;„·²½ UxrªÑ¤©…Ÿ¢ïØ={ ÝÈ:Ü‚&Œ¼eð¬ðÞ3aÀ¤µÖ·UupN¼,‰Š]Ÿ-Ë—.TWb›æ0’cU5\ôhÝhúù:šJíøæ]d[úÈaÊ”™j/u±šRÇ?Û#)F =^0¥tãbõÉŠ®Yª?>Äþxd4Od×kwEa'Є–úKªEýƒ4$Dã]Ü™5­ØÍAËšÔµÞÖ&¼ªÌŠ)´4p–9‘›!"ÁᶌړY!lI^ÓÖ¤‹eú+€ÈûNvBÓÝši3bš?öI’h²·=Ýé.¶>èíƒXºýV'¶°ñ¬‰‘ƒ“ÕkŒå§ùÝécGA'žƒâbYÉE&ÍÐïVC;¡áA8‚tP}›y fnµª6Q/›8Ãr, ¡‘ôé¸\¸ñ®¨ÚQ,íἤÁ ïmßqGn‡^؆ô%­ˆ]xm£bþÐ6S'XXyÎwิe¿¹ ;d©%¥iMØ´Ma³dC13¢UÔ䪬DX\}E]XK¿aAЂ<<[Xúu A¿ã1<\ ßéZ§Å™tOER…ë¡êF®UÎp€ìÉ6C‹ÿ¨Ï”~Rèyw1,Gδ6Ͻ²÷]¡Öü…-&ŸŠ‹a>ò ®*MÖHJ–äb(Í(ÐÚxy8t gÔUV¸æúzÆâLIèÖ"â.r"ÌM7+µ+Ô¸[µv…Z..Û×í°U•vk½9s£Ñp¡'Ûƒ2f¢nfïn Dzgèk0}ܶëÿjk ñDÿ™9­Õžïsï(vè_$îâz>[,Ãé \~»‰\gA+\y°ª3SACR‘ü³|â) Jªt¡Ðæm³Qªútt¤çóFËŽ,âx6¿[„7·KgÌ«GÁ²‚¸·æ08??óðI{|b~OcÓôàXÓƒ¿Ãœä|)ïæ—®å@š—n fitsh-0.9.2/man/fitrans.1.gz0000644000175000017500000000437112772016327014211 0ustar apalapal‹×èWfitrans.1ÍXkoÛÆýÎ_±W@ÛÍ nRYh»Ž.˰T iU +r)mMrY.iKFü=3KJK¿’ýp?Ø"÷qfvgfÎ{ât".&3ñir:þù‹˜}OÅÏãgÿb\‰[iÅR媔•ŠÅb#V*-Ž2™‹ÃðÕëðU„³X?»zw1½ÃžèMUQ©l¡Jqtpø‰®J™[q¾¹{-öðýDsáž~ØÇ’_,–¿7€cÛ ÂéqñîÓYÐnD¡ÊÄ”™Î—²Ò2µ»…óIGÏUZ,ôe¶C»2eåϸoO£Œ…çE3 ‰^¬nÝÑÄ‘'»cŽ ˆ!Ç2 U£àBfM$¶ÑƒžŠÝÎøp.ØŸÅkòâiÀ…¸ÐU¡× èGÁ´‚±e;ˆÎMŠ™Ö>Ö©ËJ2eÑ(˜¸Ø¦RAs›¶IƦ ]–L'?[fí:è.gá÷Xå¡hDÜ®t´Bdåˆ5DßÛ+•š£-œÖX,ÝÎì»ÀO©˜”U¸ ‰™½X°âë²d´¯Ä#xd´úŠ1Ci%/¤…%ÒÔ!XÒÓ*ûáµÚÜš2‰c1dÃD!u‰AøWÄ\µ…2©@ß´›mCÑñ™èÞy\âˆ=«-.Õ¾çÇN6|Ó¨£€‹òFÒÕ¦6Wél‰”!o»3=êÚ¾ E¬ŠX«Þewß5¦˧æÖS\uÓX'.9âõ¨?Œ7£`œ0­¼ïÜjEqHËï]¢ÀÛ2)‘€ê`;¼+ŠÆ}ÍàiÆ{­Ø_ÒUSê¥Î©@ä~fe„<ÕP_1ñÉè°OaRºPÕ­R¹Ë/Û·ºZ‰Üµ–Q%’´^S¡²ß¸õ{Ôp‘YVºH›ôkC÷¿22 •š$éžÀ•”ûøœFœ ¬Ĥ7Ô5<¥ä ò¦¢emIeSÙºLdä[%"á':ª(ǶàŠðÿa–kÒlÜUÅ;ê®#R€ õÏZÆ4Ý;Bsì¾Øh•ÆÏÏo;y ï”#b f‹4 6ˆFï gf Öi,b$Ϥ4Y7<—Ä›tŠS’€ºX0É…Ø_UiæƒÂà|P\¤ê %í¥¦ßË M¡¨6…:Òœÿ÷[(ÆN¬ZóÑe™#;fbårä´­‹ø Yþ* ÷àºMn2èÕsÆÁQUy<äŸQp¹<²¥Æ{jñÖx.ùx• FjheŸá[k+å³g{ªAJä5߸·ò6d” ¨m‡}ñC_¼î‹0 ·(¬9®}š>rs¥¢Z^¡WJ7ö›Zû/¾ö.$&Ì Ö‘cO¶é~qçÇë1G+²­2ðÓ¯¦ úm9 —%ŽžàTVå¾p«û·u“ÙÖ &P%ÊFz/¹©‘åò Õw$vÙ-p¥Î¯;:Oyè{µö€ã:7¾¸ º÷ºê0PÕä’N×¥n˜Ìéœ]¨ò¾Ú`ôü¬#ÀKK+™"¹ scݬȾúVÐv¨ÑÔ »éeóÅþÎ’hÃ"emkj4\Ä_‚j¦Ü½™ <MTLoް*ÇÅË;Ȳc&¹Ìu²é:€Z6tdM­.'ÜÔµT‚ž Œ&´?Êr©á¶fÆàÆš/ý8–¨à¬Ô®ýë4wZ¹ƒè”WG^ÃÖ$än5Yš hRt]¤kàênpjú±¼Eàå»w[¼„nÛoëÍï]mïŽCh›ÔyäØ}ÖÒU[U>s,øLbÛ>žšmǪPø—Wé¦O„QnGzk§È®G½|o³{wARçºÚSv‰%R'AßIX3Š1ö#šÀb”“Ë5‡ e‚µ œkôn·ÛÔÆë#•8Ö7:v_…hv¡@© ÕñVl§{"k®¨xW2Mèiäܱ0kº’À$ÖõK;i;Òœ‚ð1ø^²¥r— -sw[â‚^ÿ.ˆ®f°ÇÃÝ3.yÛª¶%³—ê)j7RùV@Ûá@‚ÃEŒ+ð:j>ýX½ÌäñFÁGoŽÁn²¦Ú8tŠß6«•â‚Sʶ×éXÝh?Õ/Œ†à6í •Ÿßï9-$î<…(‚ò6:ø‹R’Bw‘éñb§Joû‰Ák§¦hq™ JŸ"5Ü_òíMu³´S27¾*©Ü¨’™†Ÿ`ú{w ¤µ¶œIëýV.®ÐºÜ&€…d¿w\ûÀN×µRÑÉAJ£àÌÞï ‰7 É¢ ®HeŽëÈ^uk rú`#Ó}ï+ˆc…Úµ:Í%\à.˜*I-IN—x '8ª¾†`¹¤Ã¼ˆûâ…ÆŸÁßšl÷â³»CâÌ¥‚øh—‰²@ uºl¥¶Ýbã„OX6Ážò Œ[v›&͈p™Òæïid8p>$êŒUÖTζs0}S9ó¨äR´œz¤­›8ÙÀY‰÷ôcm÷Á„Äìb¤¥OÊü¹³wuv9¹š/ÎÅÉ/çÓ^p¥¨kFý[rþ e!ÓŸìIt˜«jä®þ2µ`Ī*Þ¾| Þ²+š{éßO.¿\Ï?ÌÐ:ðÞªó½ÈˆÃ7oЖñÿWóþÿ‡žèùðß?ŠK™öÅ»ݘ} :øsÛ¬÷sfitsh-0.9.2/man/fiphot.1.gz0000644000175000017500000001177512772016327014042 0ustar apalapal‹×èWfiphot.1µ[ms9Žþ®_ÁÓ—•jZ²åLR;Yǵ΋×ı/vv75ÎÖÒjJêq¿M³Û¶Róãï@v³%9“Ý»û`«Å&A 5½ª×çêÃù•:;}zòY]½;½T'§ïßü—R§µº×V-Mn*]›XݬÕʤåA¦s5›þølúãt0½z‡þï@b8ªá¥)k“ݘJìÏž¡a‘”«¢Fÿ™íOšü•^L÷ñôdŒ÷Ÿ,ú¾*2íp0½|§>Ÿ½¸q×UšjQTY’/5™©«µ*r•£U§ª¨”mnêJωÉ$ÓKc™Îåçç—§—ƒéK%ä¿\/N¯£¢¬“"·×{׋_”´&yÙÔG½¶IñûdR45^¨Cùt˜þë7—¯>ž^\ž\­«ÊªXV:ó[¥ñT7•ùÆ÷æE~W¤wí¦<Ç9“Ç./Õð-«…ÿç×ÕÅàzñòz²W‘âG|–ð}ð6¹3^)æ‚Á€¾ÁRT½2j.bWi’OtÚѼž¤E¾lÉõÉË»v­bSë$5DÍÖªXü1õûä6yŒ:¿ Z3'ú[ºÿ.O*ÉÕ™­Hqºîñyg*‹Žáœ¾ibWEU‡o¤!㘱P¿r­˜Q¦¡çNÎ|‚¹{"`Eƒ:dI§æhðAƒ.VF¸¶ãÕ¥êºLÅv.“¬LÍ.‹ Íèýö„’LËäçEQÅI R}Œ]ýzbéõäaͤñüpÑÇúhðªH›Œ„'sH¢Rs“×U‘ÄU;UWlÃmƒªŒŽÕ¢*2°íH3btš÷–C/è¢B.ÅÎW¬îWÉ|¥0*/D–Vÿg¦Ë)™ÈéÇã“q™I×ÜtMù˜­¶Â.óߔɃIÕJ[·åZ© ïh?Ú+L Fù-–ùŸP™>ð7žª 1! ‘ßfY5ÖlŽÍ¢Ù˜åú“nëL—¬³ã4v|pM§Ó]:»ÓUR4„ÂNse4Älü›óˆf…=f lä†X­ 1›òî2¥–Ø“7T¢–éJÇ h;¦ý 5¸·¾óžß.«¢ÁÆ×yޤĞé e~›Û‘’ŒÉ–fN“®ÉÔ`â0¼‘#ÑuQ­#¥ÓÔ/n~Å(«æ’XNf´c±ºOêUgWÖ°;jE¡s§¶Í§!áßIàm^LV@RâÔì¶^’X¶i …&‹r‡;Ê<0!áRu]·©Á„ÎÀ·åIÝĆ'j¿=>OePn>‡ |çí™èßæLd•w Å7VÒú±dÎV³c%¦ª¶è£ÍÑïVÁmÏÔul°  JÈëu0Û×p’¯E‘1yzP© Κ:)á²9Û¡2mo· Û)ï~z%Pâ˜Ð}ÜÚ ¿ë¡*?UÈšMêÜRu˹‘, #±þd‰ÃÄØ6w6ÞY. ˆ€No´ú²2w¤ìh'·à‡nÁ:\°—ç®6Ë"h±xRÍ›TW]ìöèö;¿°6IÊ7Ö5UoZl$ ‚™²-°ë$|!pÂ>ÿ&–ð¡‡)¨qØ¢†ál-Cj±·ëÐ@­üâlZîdÀϵä"¡Y·Y7g-¶Ã‰Öô—ÑjñJ)ãRoxG~ó=–”ÂÐŒíá-:Ñ XSL÷YÓ§ÎîÈŸñ&ë‹$f½£g'E…mÓÉŸ µÏ¼’©™nà3¨ñi;¶)lV!ÙjR`«*{gÏAê9zE`0xnÛ Ïƒ]-› !ÐùÍÙýïmÚùŠyÌ’dºmÙþ•]áe‚ã y#БÃ)iTŠ@rÂÄñ+KÈ´ÈÇäÝî¾EçþÔávöÖ›)šåʧ›l àèâ—‡Y´žŒòh!ªŽÎÖ;1ßÑC´¿ô¥,À¯×VŸw_­¥µG÷“4ïQX|HØJ=‘#ß™1Oíy})Ö¥˜+üÕõįr·$š‘Ï„ãÐxE^dØu©Ë”S„#u` ©ÀÓL<èÿï_>Fy¤Ór¥YD•Y’§ [Ýdà á„ëÒj›|5Ô æ@Ù£ÑÊüÖ$w:%³„ø4;2¬ck~lý’' Öª¢æm?­¦¢]$Ö“2ÕØ$pCfoˆõ,á6$cÙuVÖE ìœ&Yš«ëÉU(håëHöGèLw1Úó¸"A˜(‡(‰F]±˜â‡(^³ð€"“4lÿÁ³…boE™Ã!ÂÌ L iÌ ÕÍn©ÞÒÛG^^ó¦ºÓÜH.b207“/Ñ Mï_Øßªz?üóà‡xýσ± ñÙð¥Œ?t ëx ÷í!W+¶#os§ÑÌÑ#JùA颸’°¡X cugÇ{µZyÏZÙwêh§è뢷ç!bü¶­Š–D ØÞÓ/U·S‚˜±*,\mg‚@ZaR°­óÎ13l¬W€¢‘`7ÜcÀ« @\W³(‰ø-òûÚÓF" }ìê¹¶&ð°[¦aE·Î.wØXëM¼l«Yañ€öiP9¨%#!îd¦ ³ÙZ#™Œúª{òÑÊWà(´ =q´¶hª¹_L;Dôø$š=‹žL÷£§û_žKÛÓm³ý°ÑÏDA0sséNÉ<„ÔÞV/Äe²Ü©"µ¹©ž¸@®ež·%1r5r Œ¹'–u(+ ,»ÏDî~oR!v:ÛïüüöžxúÃÓ³–'G§OUæQœ—ý-ÄZ B¯<²DÖ·õ}B¦Èø€¾²aRÔ¡LüÊùoùŽ™ì¼Jn|ÞÈÝ%§ÙÚÿ§5µ*$è~Œ(…¢+õuñÌÉ2…ÀñÔ!9‘ãן(OõµèЧÓã‚vr²´Úˆ“ÉM%õjŸ>À_‹”îl˜š‹©¤šh)óÒL¼ T½¦Ã2÷ †#Ÿ¯t¾4¾ˆ €»]îk±!>ï\^*ÕM³ŠFÂ^wu¿¬þVÍ"õ)D³ÙÞ|=¾áNOبk*åUäÏbW9PqˆHÂ|ÁÔáDczØÐׂL¨ÐÌ<ÉWÓ¯éŠûŠm¥t½£öêrÛõBý°w=Q3ß­J–«zk²¡O•ËÔ$z¨‰ýTTV ¦„˜o)½5W4EãØtZïÌ<³Èå$eçm!Ã'‘zî‹ìhb[(rË$2ZW½Š:EÎÏF²_©»—~Éu6J¬—œ­‰W–(æf){Öÿ}’¦ìdׄ™†¡ÐW–fȽh>l`.¼°6°!È 4å»\°Z,  Â^³®8€vó"±"ÑþšªkØðˆ`.ï{…ÙèwY"õ|²¥fÙå¾…wUkšÝ‡ó[´pn·;°¥¦M#ƒ:²³#²ZÖ#¦â ‰ØF\d4†M$1iL’P6#\9Ž`ÎùJEÑWÚ¹‰eÝsZK‡Á!Û¹RåÈAXÚ®42çu¿à̽IÛµ ô#¹žˆm<²Í”y˜›²ö›ŽkíÎ[lo'0K|´@E›ºÅëÕBbCˆ¨Ã9=uRÕ{²H›_>ŠéëÑà¬-ÿbgRSèDH÷JBõuc/ÆíÐÔõf’B§WŽ_$Rߤ¢žY¦ä* |UöHNŸÛ¬–޾zeEwÚÐhÍŠWÚ,¦Û‰tº,`¯2Wy¼ÜÉÄëÔß>¦hi)ˆM¤LÕË é…_‘b˜¾±žø?(v´Ù·÷ãLÄ!‚Îù¢X²ðV"§jdRæ‚7 Ê‚M]‰M•tDŸLüÌÈ»=áQ2®¥lC6¢+…Ây8‹ø‡Ë¢ˆ‡ÄdJ¥aCXËÞª9oŸ´ÈÍÒ³«oVµz³®êÍ‚(ýð~ê¶®/ü'Ti0µœWíªè÷ôí–3©ô=ÀP;s¸>¼ xúîåu&WX ƒÂ3vrÜ8.ÕIï˜XÊI´Vø!Š8ýßÂ,uÒ+‘RÉ©&$*JÄî8)àê0‹š]qÙTeaM_ȉ/orÌN8Ð:n4ùáŽ8 ÒÊ[z{`ÚžÄ YÚ^MI¬Änn[Ëîp.30 6âfÎ’;Fƒ£ÿ%·jþÕ&Ý5˜_7¾¼âª>LwC/âùùÏ•©„A×î‰rÓ¹:˜^ôÔo\«º ¡òüÿ±Àa݃>pJJè~ÍP7u1ìÜ0YŸè¶ñsAX†´ùÃïB8_·™ µ®¹4 1-’%mcŸl"ã¶°ööøôÃÅùûϬ@ú$¸¾‡´ †º9XöcŠë™Ýå‚o–õ¿uDÝ%“àPŠòÕ#¨Ïå*s·MNÝ!$7\ìÖáäˆ<'<þææ˜Gücð‹QSÚÊ]>>ÿQ—ëÉÀde½vGx»×šb°ˆ³Aâù{6N†}$éwy9Ø ´Ü|6Ç÷ˆXN„ øqÁáá37üM•ተ¥»–…´¼‘¡àȧ‚–ÛÍÉí>»ÅL€²›P”ýž›ŒîVÆ.Bë~ÏMB\ÖpV0'’ö¡é–]ŽéˆKõ¹÷ë½cs—¸|ÖC5z½5øçïüóÖàûÁ§@°‚Ov²ý C¤{juÃa/8—yäöÖ¯!”ˆû+Œ€ºø f÷;JñécðºËöaŠÎý1ª,¶Ø81ºT£ä$‰’A»­KÊi¿Óq¬(<)b. ¦ÇÆ·dÈS¬‡í„µ2}k1”K7,J o|øF—íøl4_·u#J»Ë6ÚXëö2Å#È@ªÙÓSNHzl|ndÍÁ9H¨|D1ÁÒÿ¿Ú3½:èX}xÄN¸ZÆÀMþï&\5O Û l’Ê|®¦MÂM°€ÛÞmÌ’nz’x?Q^ÏIÝ‚¡U|s“ÞÅT™+éÌWj€ÑRY‚mª…vf¢ Œ³îf˜ïµãeû³EÅXúÞóÅ dQ‰»'©G`\T´˜Ü ¬,r›Ÿ`¡Yï~¬^º$‘ƒº}q8ß?úåùá|Æÿøÿ“£/_¾D W¸€ðâ0>Šl²Ìô‹C(ô™+PnƒËª-„ óˆWMhY§¼‘Ýš¶¾âb /Ío¬@¤|&§ˆþÎbZƒ~;Î ·ó F5: пÁµ±¬º(œ"w\nO×Ã$”EÐåÓNcÝPFÿ®(¥¨lÒ‹¶œÀ6QZ—–²ý­aÉ×ßÜûÑÖ½H¢;î®*tîh$Ìë”o/¥§*ó«ƒË ðȤ¶î¤‰€¨O¢»(7b#£§ƒzß ¸Ãu±ãjÌ®ÜPr NyßJwe‡w»ëž=Bß—);îçìßš*7iÀ5óÃGò ~ mh)n4:×'Ù:G›®èN¥Kwö ‹ò‚ÅjövüêÁ™p/Á²’‚TTyªÜÕ”ÎÛ(ºò$þb"s{ärÈÖ,µ3WêÒX.sÉRøXÛÚ&+[Ù °ŸsqV"ëïïD-ŽGPȦšÍF†Ù¦±sWâåÒOÆ4W¬ »õÀÝŒÈ(À‡,H’t;?wbÁ9eÝBÃîJímyW Ø}]ž,!ß®t´÷$Ú®Œ)E&;­6ùóê–T^ª»:ylÓæs.A“,/ÂEeê­+w]©œ^œüýÝÙÆh™~k„+(u¼±ÞâY”±O‹¹òéfñ95û~î6ˆÌÛÖ®cv~›É-ÚòÔý*üiE܃ ·kžH®DÒÓрʜ£ x8vk¬Ñ¿þbEï~*&d‚ÄãÑà¤Ié4¦ë tnš.‚p1¢>Ý•|ìŔи^’î'; ¯Î 3£s9‡ðÅåïN'—ý-xŠ‘Tæ¾SG(Nz¤èëL¬@Þے—ŸDWºgÀÏÍzû‚ðV˜$þµá0Déü«‡H5eIч¿»ý>èÁVïk#»Î$št‘¶µâ£f¯<ÝFV7;Ô>7/ÝL^\ÜÊUY>5uD·ïFmøÐŒàÕÎ\ A~C6üøæâüãÕ釷êå§·—ÃÁGS6½i$;8Ô¥Nÿj¿"!»?FXÕuù|oVgWônO(¾:¿øüñôí»«Á«¢\ó餺8Q³Ÿ~z©ƒýýþÿãõÿÿLϳ}zž=ý‹ºÐp&Ç9@·Ýšzð?]vL8“8fitsh-0.9.2/man/grtrans.1.gz0000644000175000017500000001076312772016330014217 0ustar apalapal‹ØèWgrtrans.1½ZksÛ8²ý®_Ë{«®´K+¶’L»6¯I\5c»lOíLE©Z˜„$n(RËG,måÇïén€õH6uçî‡8ýîÓ Œ§‘zs©..oÕ/—oÎú]ݾ?¿Q?ÿüö¿”:oÔ½®ÕܦÒIÕÝF-L¾š,u¡NÆ~?Æ·ïÕ»ëÛë—7*:‰TtcVYÞ™JMŽO~ÀÀ¼j*]ÔøâX ÇÏÆ“¿Ð›ñ1žŽ0áד_—K,›ÖÑ`|ó^]¼üåíÀ}8=Rü0+«eVÌUR–Uš IåYÝÔª¬Ô,kzW·ÉÂÏÖMV5¯xóûÅåÕÍùÍ`üJÙ…ƒÓÙù4.W¿º=¿¼Ü.ŒZê¬P«¶Z•µQåL5[Uå¼ÒKõ7»ïßTV«¦ôdîrIKnʲNè+¦L¥ºÑcE;ö™U ts‡­‹nûY™çå= gišE™Öc¨B½ý¬ó–6\•ù¦(—™ÎÕ¬-ÙgxŸ5 ¥«» ËWH85Õˆ¼' R³2øS4ŠV1Xqbð*Í–¦¨±V«W Se ž €¿^Y “²øl*Ö˜¹~ùàÍÛפÀ¼,æYÓ¦æAFèÁ®MÓì0A/)¨½PZͳϦP.æDÎ*×…«‡_£&5Ó£CË誷ٿGìh¬É–Yÿ^~{…|PœjKú˜5= ™Ñ³Y‰<èj´móbé)×¥bã ëPm YOlež¦X©B/M¾‘d>Ii°[’<&¹#kzÄVñ½¼‰³ª¿¾¾~ꦬX + 2McªzÌ~uÉ.o½AXyÇl§ð|CÞðö-~û!ãöj0½š-à˜±âGü@¬ÂïÁ;š<·kÔ-â dªïàÌ–AŽ<,I·æØ/9="mw«õW—wv¸-Œ«ÑYnRöc’Â7W¿Ï>e‡VçwÁèÒ¤™þÚ~Â÷ÒU©_Ü×J ©G'|„¬/ÜÓ Õ ¨1|#Á7¢„º\ÂSdú¨åµa-6Øúu¸0‘c¢_Ë#%y,æri9Âò-ÈkÄ“d°eÞÓšDúäsf7!Ù)F1N#þ2¸€Õº@+‘™ÆÇ꜆æk¸22žà! "XL¥áÊh„úª\ªºA¬QC!rÃÉŒÄ%S1“T¦á/›Q œ’ ²y©#U~íÕŸ,LÎf7VfÄN¬²~&#XÀ!„DüÕÜzêQ„yÔZ1;¯Žvåí¤¸•™dAãâÏ.JŠãwÉpÔ³ì;~1¸ „WpF¡ÌŠG‚:ÉAýõbr¾E OÈô]n¬ Ì-µÅÃÕÕ༠&óNmð¤Ï¦oöLSÏök±ÂÊ Ñ%†½ÈšK)€À^4=ŠÔP«œ` naÑÙ¼u eE,‘L¼†fLa^ÝW™Kô5cuð#¢õ%©0åÅF"’ž!¨è¿±÷B× „ëO#¤‚:†q¨¦¨f#sRЮçþKÇ¿ ¿$ï)JeÖ«‰¬qNIÆË94¶Y½`îLso€(:Íñ(EK1›hТ¼z æ±ïËÊÁvÂ6V-..8Ë– •å+‹_lÎ!óvI‰6ÍÈY9XsòÙÅïçb I[U4LöÇqÁÆ'WŠ€, ÀC‚p‡€ŸYë¤Áœ‰êm…½ªŒB¶ûŒæ²sŠà¦µViIAÎ…P¢/K)Âäªh©ª¬9˜u’u§ã €0ÁÙ‡Xþ}Ç‰â  :I숢“E_“^µ±W4p[éÃÙ¾˜ëF}<æÜA3.ÀÌ]æ›ØªÈH0^aÿ™Dל2Ô’ôÖˆ~/— ûûîaxL [ŽRlG°Ì·gEcæ¦ ö•d{`­ÆØ’×¾ùQÞ7~be¬ÏŠ›Ï&·ï©‡Q®(¨ŠInʦ3'b£[Cùmi0ßp“¶&—(å¦óŽâÕÈŠKh¨-ø{^AÁf¦Íb9ÁXhEÁ= 3%C1õœ=ƒlœÖ®}ß›l¾¿=ܬ٨%|€=™G´ mj²#k6D9wÓ–Š‚Z˜¹ZûÁg3Á³Œÿ8ËV*m+‡xr£k¤Žú­¦Øé—<–z^pý1þ°*ïMuúâêì£U_vCýYÖ,)NTÊàÌ’ÓM/ßpñ¹S(ÿ„A„,rsb« á NCéFøœµ9½è7S`Ì­;ÿ«!º‘‚š5²šFâa,¹Ñ~®Éø+~-Z–Ë`F)}»ÐöÌaXy¼hªª¬êÐbð´qÚãïê%Œˆ²ê*„²"1>ß°ÑIþØèO¦'HÆm®•†ï&Z±1>Ô~“t ›0èrLs»tÝDŒ8¶pÑäȵª3„šAH]ÆÎ£î]DR²ý단žlcÌvi¤°–¨Êöëé`mp0eÙDlwQ³V¡'Sº¬/ËNîµýŽ:Žøºðĸ’—^êu¶l—ˆMÙ'èyQ–0SDæJê§Àëê&Uït[×”ȵ’qBUyHA£µ0RKv@µ 뮲W™ÿ‘ÅÎ>˜¶Uû¤ ’…-hÄBCŸ­¥ 9Ðè xW³¤Üÿ&ä« jÊ}¬ÁT³j¬öùóäUdµéÁnhpe*îÛ¡­EÉ af”;l€Y)Á®<àÃVzî„— Ò®‰i][p»…9úøÐb65”Æ ì{“'0Ö Ä f¶Ða-I2Ð …Œ-Áv'£ÝÄöÿ]}×ý;Áë»–í÷`WW¦Îo{XÐ}IéÓ™ò­@ØCï»N^H\°¥.!Š¿ì+/ÿmçN¸]žý±ÝëÉí'ÏoT#Ç^¸>ÜÐdê|öûD³YmDC)™i ;½Yd³Fäm›ò[{q+_ÊAzà”"k­æ¥mšÜ™çjý¿§éúÏõŸÖ±ÚàqƒÇÍؽú¿Fô@w{º¯{€GΥªVê¬ø¢«äK£‹q¥O_\ŸÅ(ËO_¼9‹?¤f^S©tŠtYaý Æ0}{࣭íP~SŒÜjMˆ't$‡4s;+$z,ØFE 3B<Œ@kĬE 8êím«4››e°,t\VÍ‚š&+˜HŒøH³iŽØT4D_ÉZùÆnkm”UÚî ùDjIñOHjÔÃ͉aì麧!{Ê!œ¯«¡¯!¤oÍÒ¬¨€¿`íqŽÏÅ?ßÞ0õ‰EÜuÿYÈ\ÒR¶MëXnJ„ ·.%ë p‘D›¢lç‹‘å¨BfR!“¬è´`+y«Þ-‚£_9EÞjna=y¹›/­pÞvÇ]‚ïXl!Ô Ê+kí».jfß´åk-{šäà2]çñ+˰›ú®®‚£ V"A]›Ø–w]žÕ+¨j|G¢`=«OfCíS)JW:£4ÆCç. Õ¸®?¨ìùKÌøÔµ2‚c!_æ;œ¶s’¾…8äèþío/¹úùíÍà½=z!+’þ ËnðƒÎ.\“cC–躴P)5ð>èw‡LÄ>™I[빇-öÀ˜©’¾ çNü°œŸ!À¶¶ R¾7Ò.9yB yÐH­î×$ºÑy9o!~*v`ÉvdœêyM‹ÌÒÍʶrÀÿ¹•gU7®ÀÊ4“`;g¡œZ¹j—~bV¥r¶ÅÞ•Ss€ÛüþæÉ¶#užw-É\û}$ظþQM"DäTø0ÄÉ0ÛØK)PL¶œéì&$ SQIÕ&\#Y4†i&ŸÅ¶MVQV¤º@oc ÒNaQjÖ+ø>ýê"Ö OVõèGæé!)ÇÝV@4‘l%M³!·<¥£NY4Ds¶4Õ, ­}ª¢³'zqÌPìN¶¢"kƾut[ÔZyùæ×ºs/ß̲§´Îé–!>HáZ÷b-kŠÃâµ=Ž|cÝvãaoëÍ|SÁóÔõédr,_N‹¼LÞ%’W%3{²ÇèÖ‚P\gÿg$o%†we#µŽuo¥V¡‚³ÓétDâ}Rlói‡#ßšÄN×’Oè¯5ÅÛumïÑÝö"-7¡ODXÖX½²M #8EÂuÑëeÙÊ1#Ï–s?Ê4ô=„ÈyV¬ƒvXÚrÐqÞæÚB)ØÃ­4eÉ ©ºRöJà’Z³:lí,êO@ÝbÔx¯@Mºe'¤¶“çƒñùUpÒ–Ò*gÊ‚#ºó[É.‚]0.šÝñ—’µ{šTºmʘN|4òíæôx||/õZú'§'°ÑàI:dù5ÝäeÄã‰ò§!Þrc U§â.ŒÄr4∗{O‡S1sÏCV™$H:¸)>—rD´`Ó«øÛš¯¼2¬ÝÄcY-‘¿áýÈ9׃ð¢gP“Rg³Øw}0BqL½³˜X͹wέu­l¨áð.$tÈÇ‘­®+—½Ì#ö·­´YóùHàx^ œS!ˉ“®™«Á°(a¼Ì…¥¸ÚÕ5ŽÂÜÛ«UQ§¬Èò܈°íÛG{ŵsñI>÷Ãuw+cÏíÙFnI©ÐË2Aˆ*̺é9pÿXjûgÂwt •(ßyäm§;9d˜YeóŒÎ)]”ÆFÔiL]Î6ñuUkNë r»‘c½éÇÞÆ¡÷—~€{?Ýp ×ûT¨\«[í.l)³œzéúÌS‡GÄH%ÔÙºk%;\â³™ÜŇKt.ˆË£ÌØUÎqIp^ù¿Åb ¿Qì±#A!ÞÚïìö·ÅÎq¨¢À…§|ð¶eVøÒŸÂ0ò¯©/±ù©‹û½ÜCe§SË`RÂ?ÚÊ`g´¦t ­ Q'ö™½Û(s\Ÿ³ö¥tdK¬è4b`I•åLÙÖô‚få7Ðî Åó‘x}!Î/®ÅÙÅëéé¸~7‰Óé/oþ!ÄÔ‰{iÅJª’N¥b±k••ǹ,ÄQüí÷ñ·q_¿ÃüÙõ‹+1:‰ÑL•Nå U‰ããï1°ÔÖÉ ó«ä;±wÿÿLßâC<}³)¿ZLerÈMí(ŠgïÄù‹³7Q³t~ RåTât±˜"’µ¬dâT¥ßÓPitá2}«„5u•(Ë"f7ç—³é,Š_ /)ú}¾œÎǦtÚvþl¾¼úCðЉ.ÊÚMùYæñàÀÔãâÄÿŸø%,ýõ›Ù««éåõôâ<º^+‘K]ˆ²®Jc•0KáÖÚŠ²2«JæÎ4‡à¨G'hõ{:V± çþ fñ'æÚ}±¬L.¤u•)L®™ Ë•²± ]ýúÖ<¦…ók¥ÄBZø/n])RôOSa+UBÆ©®¬‹R?¨L¬*S—–פ°íVݯu²æœËêE¶ •çq8^pð²R™Îu!«M¯” Õ3™¶hªS„•íÇb¦S¤cá¥ôßxenR•e¤vkÈiÛÊ‘•e!³Ó‰Ÿ#–u‘`ñ€/L…Cx³ÓY0£býM;¨Õ%ƒyЗ÷‚íìZ–˜†øÊ¡~Õ˜9ƒØd'[÷‘8úæ¢q<Ò€-¿w9;…÷`jšÄ>‡®h†wÚ·;ccÐX¼”–ÜmÆ^h#/ˆ¬¼†f ;‚„Ü—)^Þ2©OçA:ù*4‡êuàQLו¨”-É™°cŸ|†·1gÃ'Rm6£· ™hòìGdôõe4_¾œ¬‘?cÁx–à=z ±-ÌdÂÖÀ„\@gÖ6ñÈ­ Õ {™Èd'n(Þë6‘td©ÉЭ >)ý^ßêIçoÁh®R-?¶ Ÿð¹:QLŸµ«)rézÞ!\11ܳ:°k$LøÅke8»šQìè·a$éÜÑ„^°÷À¨'>—8Ù$:G>ÑÉš0¦°ddó" e|ŠÁ&&Üć3ïœO6áìj‡±…ªÔ ìéùË¢µ»¯´sªˆ}´sžîâ Ny#îȈW¡á™,å“uo“èu'·TòVt_é^¼þ5ŒØe(q™ÕOåÒ˜Ø)|øe—ðùÌVXç,«{›D3o‚Dz씡vVL¤ðN5ªKÄ÷íHì¥j)ëÌí³Åˆ°wa2I;’ 1ˆ*£ŠD±ýë$z…QŠ$û°ÿÚ»¨ ‰µGâN“@ÏkFhÖ«}¬… ¥y8Š'ØH q5L¸ [°¶þQ,aSÁná«%t!®¥–T°˜uõ°/¯ Ï0¨‘5d€ qu ðÕK„e+Á(—tì¾ðpdxí¤Š!^^7ê4’ïdV«A<˜"ÛÌú’MXòÚÀR°[qg²;*N®Ôz«R‹´®ˆÂyµP§›<ñ9ú·«4*+P¥)ôžC0º ¸‚Õy 8ðî‚]]WÀúðrì$~šüÎ,âù ÿ›ü½Øæ¬pM–¹ í°b4j ¡OòLÙ¦ÁJÖÖ" ì&Çi û- h|E¨‚íÅä@<Ì“3•«vÍdëŒRu§‰°còÓO|*A_² ‘$L]v¬ÎÇq:øþÀFÚQ;À †òZC™ç'ÅdÜqzfV\ÔÜ À ¿¨;Uà…úLVÕ²J ¨0ž’:í|´ãb=5…b[ß…3Ù1>‚Ézå[º3÷2 ·¹ã¦µäni²ÌÜ·ï÷$Ò"ÖFåEìcïK®øïÃãæ‘Ðìqy¿Îe^>Î>LôÑ>+þè¬\HÓÚBµ]¤ Öo“7ANŒ}Q`ðÞB-drKpDV'Jµhä ”Z£œþûÝY³VV»ØÛZKh.wÆ!Th¯±à4ó¨§Ð+xÕÆÌü'vîOA=Í6Ãt“«¦DqÊÉÕdÌÕiÉU¡]*êþødHª–—ðŽMÔEjÞ­¸×p2KýUP2€Èv\³H/§Wèl›Ç@E{»Åf¦Ìbè“§ŸàÐ2MÛø[0žóðúX ×]ÖÇhî-÷¯„H\bHé‡$Ã!ÒÀž`¹q€@Pã âtjÒßÔ½íÐS¨GèÓ]`¾çY?¢ž¨QÀ»€£úï(GÙ‡ãø×fñ§B9o$4®Ì=â:[ø‰Ð}kfÐÅ4{öndj‡2­É4ÀR8Ô¼ÒÎþðªÝ¨qH£¹ŽZO`ði˜‘÷aÁÄËmCô‚9 Ó) ‚¨ ýW ë¦8iUu]_£ÿž,8ÅVøä‘™ÕæYõBÊOø-HìNPW9Tü’M·äæo.yˆ^µƒƒ] Ká™R0ÈéVp¹âÅ›~ñÍg/^¬¢—O€…Ç…Ñ%!2N^žE]ÙÊQÁa³Þ¤•”¨E±½Ùó£gž\þçxŸ¿ŽÊ¬¶D¸Ó©à>,×ü+J*c?sïêÿ¼òƒŠÞšÂ«5ró8þæ;ñ•àõ^s;'ý_±78t0ÎýOoÄ’nÁ"¥ÿ+ö†Gû\QT³" VXMƉµÌ–ÜòÉö»ê¸C“—¨¥0Tg>2Š—ÅÈ7Q«L}l2ÁxtÝ•¤n*'Ï( KEça¥ÚšƒÍv¯®l93/转ôjí Bä\Ê‹n–¹ÊÈ̱£òyï'HÏž‰ïLÔ½–¹pmðD–ݳÙP’Í.a7_(lGú>ŸŽÿûÛ‰ýÄ©—™~ :¾Tðí'ñå %øõ$»aèͪ##¼.¨¨¾ž],PÝŠ¶\ûKô·˜áuZo»ô=wG€Ž€Óm‘„€ys;ÞëÁD®‰.üÈâW•NŸŸÐßIÆIÇ÷}Eà žHðCžŸ0Ñã„¡Ío6€µòÒw¹ aáwþæ¹¢Ìîå†(•8þ*úõQ{'Ä´³ Ÿ¨sƒó@énØ8ËvݯnψÅñVS‹àmM4óæ®=/Û›¡ðgºÑ±JVɺoµÎRR³¿:±Ÿú˜ˆ¨âá…@¯“X•6Éô" 1coÌ$;Šïbg'ª"ôB‘N5<ÕK슗ÜîٞC~Uä}P•Éúßíü=-ßûÝ›¥ÉÒî—2akí䂬¸ä[Ñ4¨p4éN5MÝð,ú­¦½âh‘ö§æÚhÌ‘=Lµæ¢ˆï=x7öxI¦d@n³ý¸s«´îüF—zDXH¶ò&äVkġ®0»xmíÇÑè麧7\Û‘I¤$ptsÜd\ããÆllòïÓŠÕm5¸.H ÚÃÆ'É&cú·¡ú“Õ95Y©nsì7«›wˆþ7«Ñ՛ˋ«ëéù[ñò×·³Qt¥Jº‡YÔ+nÆOd)³Ÿí{°Í¸Pn2‰[;WþøìðÖ®éÛ3/ñÕÅåÍÕôí»k(Tn˜Šù^bÄÑ?|?LJ‡Çü÷Ûùþþ“žéùè»ŸÄ¥ÌÆâE‘VÒnmý‰ú‰Ú©fitsh-0.9.2/man/grmatch.1.gz0000644000175000017500000001306012772016327014163 0ustar apalapal‹×èWgrmatch.1Ý[[sÛHv~ׯèE*5ä¤-×ÉLdÕÚ_T5–T–\É”åʶÈ&Ùcà¢QœÚŸsë @PãÙª¼äÅqé>÷óÓÓÛLýt©..oԇ˟Îßþ¢nÞŸ_«·ç?¿ù“RçÚj§–¦4µnÌ\ÝíÔÊ›“µ.ÕñôÙóé³éÑôæ½z÷ñÃË›×ïUvœ©ìÚl³¾3µ:yzü.,ëµnf+õtúÃü¹ÁÓ“¿â½éSøëû1<òÉÁ㯫5,ß.ÎoójÓØªt·On¿(º4©Õim¦6åÌœ©‰U§¶Ü´Í™¢§ø½I¥N«¶ÁËü.íóÓ›ë×ϯnÎ//ŽnVFmêjYëµú›lú7& èg.j£çjQWkÕl+E»¨…-ŒËU©×¦ØñM­= $Ëä…©zYÊ®7…Yƒ,@UºXVµmVk§tm”ۭצ©í,‡·T´¨A­ð§nèwm\[4Ê­ª¶Mºè€ eø·3D$‘ÇKnõfcæS…œV%;ÓðÐvexƒªž£BüËü¢uHeU7ºlð=­ÁÄ*&Oª©uéJ TƒéÂU@_ÓÖ%p6r$[YXÀ+È-ªíXxƒ7ˆb‰Ä'˜¡‚yutÌÈÔHìèŸÉ-m¹G ³ÊªÕÕÖa£eÅj«Öá^÷º¶U T€LmõœEýL¯õžG3Æ›£4j¦;1iyE— જ#–, V×wh¬w¹r=3·g6šuVíºtÀX 6#Z'þ§ê¹tQÀ{½Ý,Jgb3µB¦ # ª‘™.§Ê’ú€4횺*«5é¨ÓE•z䘅vgVú„â "¸†p×´¨Z4ÝDõ¹`I ´·uE²ç«Ìį¶`à‰†M§êä€ÀYAZÜNæ\Å îÔœ–Ñw¦ê\ ¬sUÍóéæacfhEÛêv‚¾á%~WYìÖðxÏy/-7/ˆä¹Ný7=ù ,N†Ø Îμ0ÓZX×°~-«mÙ¥ < VoÐ[a¼^PW°ÅÆ<ælLP¸ÈBº„¡EâEFî$Ü”ì,}„Y¦ÛÀW®À Öàº4à%dƒz5Fo°vŒøm  Û;ŒrhJ ¯õ<‘lW˜pЬ:lNCÖ7Uß?n4Þ× .n'c•ZPTUŒJ‰ÝD# vk\°™Âdþç8WÓé4‡¿.Ôk]ƒÍXx*1¡ ¡C;×®líÝ’ŒË O"¹V¤‡ËŠàg¿{ùÝÝ^Û*Yö»«äÑÄ(ØÔ4)\²šÄ€FÞÓè쓼 rÅuq«{ c4×SJÇ—”‰!ë__«LBž’Œÿ# Œ›«£ÛÅ«ÛÉ x®èOø~½³÷F O¡@PkмÒwô™>+” üšÓ¸äí¤¨ÊeX­»:ß“=ñ¹i4hwÎ*~wõ­ýj­N÷’«k3·ú±â”&4’þmÅ^סµ¦{úK€u“Þá É;¬έä"l˜øvІ¾dë×éÂH:ä\ñ5ÿÉižœ‘à…^ì@‹NC@/§lQ—"ÌZdOdAþ yh¦÷,­t‰«*i xÆßxö裛 ~9„ Ò†ŒZÓ-,­H—6÷x§‹½Î@ó|ÁÑAòÀ_ûˆByò¨uÚºâ 6Êã")Ô?ˆ±žY'꫈AØPþýØ­‰Äìô™+¢"ä%G<F^"MAņ-ÜqŒë\¢t»Àã/ä‚©j Tr‘Xر#g`×ùþãQÆy·ñ1Þ7b?Ën^¾R³$ÃYƒç¦«qQ]äR®•U0NÔWYA`ƒ§E&[ 5ĉõ^Ç“½€Íìhç áž¡VCÚˆG«¼J\”Kfc•Ðõ{]XàHóëˆäÉ®,IÎkœ…8·îWJ(áQ€º÷ÖE¸Ž.šjiy 9è倖… 6!ÙØy—ÔÁ¸ •L]ô$Ò³Äs™-e¡0$‘c‘ŽªM`¼$'°,E¸ ä/ó€· i†}SRÀÆBø,HÛžA”Qz ÄnA©6(šnhMÜsïÖd?þ$NÛ÷ÙöëpªW-$_Ï5`HIR¹ÇC²ì—#X¥bk€º$çðÇÞ¥V$z¥Ìb˜Š†¨’p@ƒ!q1/èñÈ…-É ÇB×½®±3—ä´¸?¥¦ªAË–:+¸˜ø S܆ –˜M®Ä9þÞÚn¾¾ú¤Àª>\qe èpÙœé so »ÁúØÎ[Ð%-˼7H 6.¾ŽO®¯®Ž BB×Mù÷¦› ‰ßnJ±Ò, j¥„ŒquÏSr Ìn'™…tmKpUg—剖˜ê9J*É7“·€½ÉL*¼VaD¸¨Ã-¤™ƒ«§*Æ6J/  ªì_`gÐï |îë˜ÂG‚·µ×qÎ%ê«S  þ›O'á„®i¥Ð@R×í„Ë-Ä*Ñ}H÷ü±­ÓKÓÅì=CžªW;Àp …VžÖ°”ú#8Û…OFÄZV:I^Ê Iôÿ±=úá,?Ýå{Á!Þ;÷ à¢OϧÊß<ôz!_®¦Ù¬ ,€ŽÅ޳8ìcb0Æti@q[½sêØC˜äiI×ðÔ mè*… ®m¨˜)ÓøZn^Q8ö©Œ³˜N!î ±ÿA‹Ú©æØˆÍ³$ŸâÏäF×4|J÷åz±Ã~ Z^Ò‚“¦(ýpµ<Å–¯ï7ùrWaýmQœ¨°Æ,lDG²¾e6çîÑË\ÁÕÂLR£—ÿv<þ3ü{2~r"rn2_ƒ9ý±Ò·{µÌ‚ºÍlŸv}ê;=`=N+ø[,~AN-”žÍ°m=WþYA³5¦Œ¡ØÚž$%ÿ@»#¹KÔÙ¡,ýøÛ‘ÿÞ \®¤"­‘ŠRdK—ç­ñm˜Ø÷Uér1XHbµváÐbµB=þ¦Xá•Q4 åB×Kî—J$šÅPŽÿnÐ(ÔÖ$Q“Rq¨!(.wÙLø‰ìÄ&KM;gw¤¼?35y÷ñ à'€Êp С‘KÇ»-¹!ƒ–è»”Sua“Dž°¯ k¤ÐÛOM§?c §¯)c0ÚÃŒÆzÁ¦ˆ‚xˆâ«C°Wr9γ×FZ >`A`êR2'D±È0›ÆBPCö–z]7-½ÂâŠßú oeÜHÇ ‰JôorÐʬ¶we^F¨íÁ Á$Û^†Jcê-Dp)±z¼×¦_åw—IŽ8î4no4˜Q-m?¢©Hž|>þ’«Ï'_!|þþË#¹z ¥7˜°é¹NÃ%¹¾ŸÈÜÒIãCDŸË£gÝ™™n]òÒzGBvhˆ÷ÍÁ÷¯«˜è1¨"y„:Ƨ5RÑ£!'ñ@?!>†ø|úÛÙt:ýòå˜è=õM¸ÂuØN¯öÿ ®À£aŠí&„d;Ö©•N’²Ð* ÖÀ;6ë︀”J£H¯–¤l…þˆx%&+ßzøWè-0p9¬%ÒEû´>ãƒ#ŽOñI’jª ®Òy/e nüÏc,9Á"ƒÜ…ï¤bøï„ðý”áƒÏwŒ,Ƴ_1ž}=õ>yô:=/˜Ö¢'ö`ÂRþmM´¡Ð—rRVP±¬ïì²µÍ."EÃ÷ Ô>ô¸]÷Ö‘4ñD«xRGÔí(ï¯)ˆ­¥š•sãj6kkæÏÏÕx*;àå¾Pžø¿ôÀ±!w@¸é;¹¾šoDÎ4”Ls©Í-[S7‹v6ho¯ÐPäLDœÁëÎ…BÔîÈÉp6¦DýÄI7âÏG¢¬8Ô®ìñ0Sá4 ì~b™åÇáùu’‘‹£ ‡Uw-Êá”kðŒ¬ÁWzÈž“ ËâÒ(˜¯ÊÐÔƒâ®{KÞ õ¢‘HâÅ{þ` $#& Ë²ÚE‹*ÉK×$½‹¯;7ö ôý—§^˜T¶êuÕ–áÀQ+ @ÅL,–8­È3>Ô-Ç·ž7«ÑŸÆDÃ÷5†€ml³Æ´   Æ} © ã@†w†½¥®áÅ“‘^“%š"Åì~Î0“*ɤš¨÷X”›qpª^Æ+òÚCƒe*•»ÌAN1 öç3!\8–p÷…OI)Uccݧ,AùݦV îɧ°$z2]ÛLšÀQsÇ@•¦9%ˆ&1•èÁŒµÃ‘4Ѝò¥A´è,Wì¦ Q,š½.%&Rz¡@ ˜h ÛUåw ÷ö…6|læó'ZKw>ŠmŒP1yᆞÑx2ktº6XHgÄyéf›!!<ŸÛ¢ûî™Lù>N ·§™œBŸ¤!g=yMîÄxÒmv½¸j€¼_‡÷îf¢Ä̯ŸžÚAÌi—ß½ úBàÖ®ï¼H‹ãX´lŸ´´BŒ†8FóiÂCÏ<Àf“©•® êE:-©;1à}$… pi‚Qfâ‚BŽJ—zíwL Œ$Ô1Äa6«ô2ÔΚb.¥Oû„¹ü£éV­«¹évPç¹XŒ)v:KùœD-Ž«8J¾À €!øì~Õü ~س}7N¡o¹Äˆ+‘=6Q2êåæ5ñÄ·Ùm|g*}dLÏ¥Ù>Vg# t¯ ÃCŠe2f(#™eÌPÖ›V¦¶ O•^+ÒBD9°Beßîb¨X顨ö¦tÓ¡[/  Ð÷ôŸidà)£%³+a(1È(,“ãŒTg(/ΛS¹íÛŒÔÁäp'v `÷§£´å„<‚¬°æ¡b€Wâb°"˜‰éø¥càl@ƒEL2äªëeË'ú±F¸ÛqÝà¦ãá{ZçTŸo'_N·çßCOMŸ=ÿÁ´+<¥A>cWÔ<6ƒ~Íž€Þù|–1Ž|ì:“bS¶\o ”¥¥í¦BOÖÛTœráÙµxþb*X½ÂÃ\ßÌm<Ò̯¨|%-¬Ó7B/™Ô@ô=ÎV2A؆Ÿ†´I§ÀC±¡kfæ'Ç>Àr‘\Vª4KMȇMÀd•|™‘2˜‡\Ú̺Ñì)Åq`«SâX ÒKâOGEb!ÂBï'ax×àÛ+º®H!¬¤Ï¾óÅ î  ñ´kOº˜ä¡˜”ΨW/]â9iÀ"J.fã!<¤ßÙ89¸’L¼×d«˜P’cXÈ ]&d(¦Š“¢ÀôLÅQrUl" ÷2&Ú(TmÒÝÔsŸçl¡º’Aè&PB:óýU•‘]f>¥” ÄÒ‰üíåmOÞŵŽóøŒê¤v};ÁÙÝ®°–É$Ùè;N }§[çüñpm>Ñ$uªÓÞù¼|Ð6Á8!Êà:z‰}Ð ýá¨Ó^zôCàµÑØÒɇè9s»X`̈ö ߌ ~ÔˆxhAÕø§ç¸õÜ23^WMütЭì¢aæ0Ô_¼×ò"o~š¦^” |sM&²·ŠB0~n‹ñ’»½‰öîvôÉ»gÒ æƵ“k~½K°÷bÅš }™W7¬ ·¡Äžý–Ä™­emMDºZG¿ÇX¹Ñœ; ~\í´6m½AUæÝa»ŽÑãÇÕôpÜ!v'z lVD×O¦ò>` æ{wÂ''cIÑsSy¦˜Ç1@ý.ñ©Qo<þ^eß\]~¼9¿x§^}zw}4˜r¡>Y4=Õ]üÕýV-ì´4ø-Mh‰®šfóã“'gÝ ï=á__^ýòñüÝû›£×ÕfGOÝŽf•:þá‡ç¹:yúô„þ}v;ÿÿ>~Šÿå?Õ~ô²œ× ‚þÖGÿ D bBfitsh-0.9.2/man/grcollect.1.gz0000644000175000017500000000542212772016327014517 0ustar apalapal‹×èWgrcollect.1•YëoÛ8ÿî¿‚§CäNVíÛ^jì6MSÍqú¡¨ ,-Ñ67’¨ŠTïõþ÷›%ÑŽÓÞE£Hœ÷Ìof˜d‰wWâòêV\\½¿ÿ,n?Œ'âýøãÙß„;±’V,T©jéT&fk±Tyu\ÈR%/^&/’ArûAœßœ^}üxvz+¢£HDU9UÌT-Ž^‹EšY 95°Ïl4H&Äåogƒž|:•ªç¦.t¹®–¥­ŒÕN›RÀ?·TB—Uã„“³&'3é$±š|¾¼ºžŒ'ƒä­è8¾Lçãil*da§ÓùÍWA¯NˆÑHл/I’||vhĉi~ü>œ‰“™´ª”…15Ézw69½_ߎ¯.· T!u)ª¦e•0sR´ªÍ¢–…ø½Sæw¡­p+37y–ˆ÷º¶.Úá[]:Uf`Ž3"3dÔÌÇï@š¨$x¹·Zêt‰Üj%31¯M!æ:WV˜ZXN—uÆg÷ñ”55:Þ [åÚ9oU%1<íj©jERøˆÑ+*%Aš­À:}¯ÄZ'béÑ ‰¤òN•¬Í¦‰—Â6 ²)° Dñ!Cd…©[mPY%Øã÷¦Ôß<< AIçb`!©²Ï¥"íòëžÕeª|¬.t.kÔ9‹Lª´pNæL\HWë:ë@-ô'iŒ9+ ˜H¹Ú¬8¨ÀcÃ1`JånÑá­>l: ðÁ%Ìr¨)Ê<÷ÉãÂq-æJº¦¦ÜÎ;J,k EÇN[§S‹$ó¤µ&ÕÒ§B¦çsIé(šmd2p]ÞdJÈ{@…{…’e, •iúi2µÏ –Jȯ¼Ýæa¦îAeví øDc_(à_ÐgÈ@í–ä®bŒ¨†õ\@µæ˜W¼jcÈ©‚icðZÚ“2ìM¨¯¨†3&æ^Ž} u{=˜ÎßN‡K(ýXÐ#ü ¿Î1垈„Ök!gñ ÔMéD®ËVw›ô,§ÃÜ”‹ŽÛ&wþæe€Ö`²“S8CÐèŸr_é;ýwú¼%ÿÿˆ ?ðWuÂŒ½h©©L¤ÛÐR ,”Ù¾Ú%¤jø…_4Jkÿ²|î£áá˜E·àÿ¥m±À0¸œoñ›1+,¿9‘+‰pµ‹ïhÒäÐ2UªçZ¦ßð"@lmB.@P‰§A·\ÖX<¥ ?€[&íRDÓa„ÒKØxq(€GCª…O¥Ë%‚PàÏ4ôÔÿtˆH /Å Bf‡"™z NƒßP1²1œëáÝc´ô¶¦»jdŠn»&I&†ÏfÓ!5ÒÁ[Dû2ð5÷[Æx†³YwÄ‚«¼¿S‡ÝVúPD¢g³Í"A¬r™òPƒ"6»TËÕwÕ:f‹&„æõÞ²‡Ð2õà¸%iÝo#`£x`šë:È£ÁÙ·FßKŒ",„|ö=ôWwðÙ, ˜G‰¸4;سF-Á–J{^z±t”!Ægº« q§þÙrE7aû^4Øó(ߺo±˜ù kf ®qž.C·Ã<€Ø—sÓ= c"Š2ã"PÆ­”*Û´"éøF:ä+¹Æ´‡ùÐ-U#Ö?•&¤¥§Î)?r,! s_i? lØ øQ¨$èéfÕ0´ lÆäRœ¯øòØŒm¸¦QŽškô÷h+ ‹æ»Úâ+Fqé{ì˜T)—etâ[#K@U­B]®øÉ~Ž‹b0ÿoûËó€ Ú옹YõíÖj²y´‰Ö+·|-ŤÎ@QÉl\Ú3€Î šãÿ„[ÈÜM ‚œ°c\[ U=]£9ñý–À‹èörÉËŠŸº°[ážaê.åØCP÷¯IIÚ·[¹@Þÿ´Ó/™<#UíÉ6â뉼·jõΈ/¼§@¬i¹ã•Ó7¿ÎùÞí1ŽŒ ¸ßΡ–qX˜=;SFtyáÉöY—Ç»×à"xÅögùê]Ac{˜IÝr©Ÿd?isúrúÎ4ß‘à¿Öe°àÅâñx¦/|b0ñËb Tøƒ§‡b‡6\)í–‰AWšâ™;VÎ=–´¿c÷Ä–¾1K?∈)¢¶ÚR7,Tðcæ±P›#ê멽“ŸöÍŽO­sjïÛ6S¼µS†‡4‰~ØR‘SS &M:´¶Uâ±¾ó¢Œ?Æï˜‡- ܱ燼~̧ÐRù0¸€ ¤ð$ð;=SP!Ø6K5åæÏÏ{±¼üñèÊ œ8꠺ÈR ›oNxkŠOzNˆP… ì€-iWFôho)zêSºÒKâÌÛ% Ã¥% $oNÊÑàMÿ÷ ÔÀ$dfÛN ŸÚ[¨]ÀÑê›âdÕ•g§§ÏŸÉmÚÊ™£œzX_h7êDü_7A‚„ö® xëçèV“ûÍ~^Œ?±E¥îUê]_úq'¼UCÀXJ¨ àÆKóÞÐs,M†“~c¹“Ÿ’÷ÏœÁ»„h×eHÛ´ÛõäÉe ; Æv¬ÛÅÆŽ|ÀKÐjM}•G_îŠÅ×.9dA·a †? yË“œåÚP6e oL¾Ñ]ŽEèòhm˜”w:7³µÃ‚/ÔBÒ#UäBûßâ`ÿÆuñªÏg(»¶N6öwŸ¬¨W –¢É—‘Ï;fá.®™±¸#b ~ÝÅÐTT ¸%’¸þƒcÊ·£Xa+TeÛgtaï{vp[Ÿ´p^b÷ArÊ&w¾…‡_ïÐý{¡VhƒÐÊc¼–l*Ì3ì,÷jçe5®Í…%4C˜Þ©ƒw~Ù÷÷Þ\ð°25^šVE™â`‚7Nëvû©–kKËÁvJȸqçŠ €’¬ÛsGƒwÝÊK ¡ŠÊÔxÊWeðA.T6ø§?Ý/ΛƒQÚÔT“Xjý_9àßf§õhõjŠä ¯ø+~¼:olÛÐ\/HAú9*ü+Ïõ¦&>>XòÐekJ_w-Ï-”ʶýœt>“Ê~@Sùœ/¥£›³ë«›Ûñå¹xûé| nT…"fÍ‚2õDV2ÿÕþiæ:)^^âî@·Kçª×s`·ÄoÌñôêúóÍøüÃ-t©j]ÓMÑt/5âèÕ«—±8><<¦ÿ_L‡ðÿ/ø|tˆÏGÿú·¸–`üoo0gl‹ü†m#bfitsh-0.9.2/man/fiheader.1.gz0000644000175000017500000000214212772016327014304 0ustar apalapal‹×èWfiheader.1½VKoÛ8¾ëWÌêä6g³Á¦õÍÃq4¶a¹‡ ê–(‰ˆ$ "Ç‹þø’’-¥i{Ù‹E‡ßÌ|ó IàÂÝË <.ï¼û'ØÜ{Ÿg¿x vTB VQÅ"Øî!eYyžÓÆäâ’\‡lPÿav}7[ƒ;vÁõY©X¾eœŸ/Qó”Ñ÷gä*Ã?äü“>$g¸úýu¾H<¿9BGÒuˆÿ‹ëÇ™s¸Œ Â/@@=^ÖUZpïm|hôžÙ~'ªHÿi±\ùžïh‘œ¯AìCQrQÈà4ˆ×ßÀŠxQÖª'‰ï£‘¨Êab¿S«`àïfþíÚ[m¼åÂÙ¤\BY‰¤¢9Ð,; *ePëÀ”0ÎA25ÄS…2Q¡,/ ¨ƒˆá…f5“@¥!7Œï¸J Œ,YÈcŽ¢6@ˆ+‘›³²â9­ö-uÁ (y&”€äy™íÁµgî‰6C-ax)aHKƈ‰fiA®|ܹIz¢Tš§˜’ÍÊ â›`”büC0KÜ`=àÞ™óÖ–J²ÎGt‹¤C›ZÈxÁZPrÄ F™(’\ÞžŒPˆ˜¢è¶F“†¸Eßñgþ3tsÖ‘æ,âôWŽ ÿÕ'à<¶·!UNUÏÏVITìÚlE#™ŠJuO¬ s§qFŠœA#E‹ÖŒ^ÓÑjÇvÛ ñ&Ç"™: Џ™0ïÔQ 'ºp¶s~‰×4Ù@„8j¶Ì¶€V§²cþ¨xBlÙ®±ÌÛiÚ©[ºI׫„õØÔ j\l®O‡„çs“ÍC×a+ãEÛ|¹Ó ý¾‹jÉ7¸v9uîÍ·8N†’†#+©µmiZ%uÎ %õ,ÍXD¸CpŸôÒ„êê™âêºC]”b±éÛ“¼BDTíùùÚõ“½*V4e“Ãnê¼Ãèqò$Xo´|µrBé„aˆû%ÖE!ÅÛaб…zö•Táû¡I/ɨu·µÕL¼¶Ý¬ó{­G监ß˰ì5H?Ãu!µ½ÿ51!M¿žNÞ¦ßÞÏ{;‰yÛµL t‡ÛæÆ±×@È]%–ô,êpN»þвdEôúc "Õ¸ÕT³WDÕlfoÐ;G]#–±7 þ´KО}ߢc½üÐ+¦AB†\hªtâs‰W‚Q ¥ÇÚ¬ [jŸÎVËVÁÁèËÈòÒZSpÒ±´ë÷ú®â&¬o<Ó›Î\ÑM6@Ö"ì›Pe{ø÷Ïñ…·Ü"saVK¬~|[Mt‡¡÷ý8ðì³ê®g«åzã-æpóeî»h±Ä¹ Û:1 #include #include #include #define psncpy(a,b) memcpy((void *)(a),(void *)(b),sizeof(psnterm)) #define FRAGSIZE_TERM 32 #define FRAGSIZE_CONS 8 #define PSNSTACKBLOCK 64 #define BLOCKSIZE 128 /*****************************************************************************/ int psnerrno=0; /*****************************************************************************/ typedef struct { int offset; int length; } istack; typedef struct { istack orig; istack diff; } dstack; /*****************************************************************************/ static psn * psn_alloc(void) { psn *ret; ret=(psn *)malloc((unsigned)sizeof(psn)); if ( ret==NULL ) return(NULL); ret->terms=(psnterm *)malloc(sizeof(psnterm)*FRAGSIZE_TERM); if ( ret->terms==NULL ) { free(ret);return(NULL); } ret->ntermalloc=FRAGSIZE_TERM; ret->nterm=0; ret->terms[0].type=T_END; ret->cons=NULL; ret->ncon=0; ret->nconalloc=0; ret->nseq=0; return(ret); } void psn_free(psn *seq) { if ( seq==NULL ) return; if ( seq->terms != NULL ) free(seq->terms); if ( seq->cons != NULL ) free(seq->cons); free(seq); } static void psn_memory_compact(psn *seq) { int k; k=seq->nterm+1; k=((k+FRAGSIZE_TERM-1)/FRAGSIZE_TERM)*FRAGSIZE_TERM; if ( k < seq->ntermalloc ) { seq->terms=(psnterm *)realloc(seq->terms,k*sizeof(psnterm)); seq->ntermalloc=k; } } void psn_append(psn *seq,psnterm *terms,int n) { int k; k=seq->nterm+1+n; if ( k>seq->ntermalloc ) { k=seq->ntermalloc=((k+FRAGSIZE_TERM-1)/FRAGSIZE_TERM)*FRAGSIZE_TERM; seq->terms=(psnterm *)realloc(seq->terms,k*sizeof(psnterm)); } memcpy(seq->terms+seq->nterm,terms,n*sizeof(psnterm)); seq->nterm+=n; seq->terms[seq->nterm].type=T_END; seq->terms[seq->nterm].major=0; } static void psn_append_inseq(psn *seq,int termpos,int n) { int k; k=seq->nterm+1+n; if ( k>seq->ntermalloc ) { k=seq->ntermalloc=((k+FRAGSIZE_TERM-1)/FRAGSIZE_TERM)*FRAGSIZE_TERM; seq->terms=(psnterm *)realloc(seq->terms,k*sizeof(psnterm)); } memmove(seq->terms+seq->nterm,seq->terms+termpos,n*sizeof(psnterm)); seq->nterm+=n; seq->terms[seq->nterm].type=T_END; seq->terms[seq->nterm].major=0; } void psn_append_term(psn *seq,int type,int major,int minor,int cache) { psnterm term; term.type =type, term.major=major, term.minor=minor, term.cache=cache; psn_append(seq,&term,1); } static void psn_remove(psn *seq,int st,int num) { int l; l=seq->nterm; if ( st+num>l || num==0 ) return; memmove(seq->terms+st,seq->terms+st+num,(l-st-num+1)*sizeof(psnterm)); seq->nterm-=num; seq->terms[seq->nterm].type=T_END; seq->terms[seq->nterm].major=0; } static void psn_insert(psn *seq,int st,int num) { int k; k=seq->nterm+1+num; if ( k>seq->ntermalloc ) { k=seq->ntermalloc=((k+FRAGSIZE_TERM-1)/FRAGSIZE_TERM)*FRAGSIZE_TERM; seq->terms=(psnterm *)realloc(seq->terms,k*sizeof(psnterm)); } memmove(seq->terms+st+num,seq->terms+st,(seq->nterm-st+1)*sizeof(psnterm)); seq->nterm+=num; seq->terms[seq->nterm].type =T_END; seq->terms[seq->nterm].major=0; } static void psn_swap_sequences(psn *p1,psn *p2) { psnterm *w; int l; w=p1->terms ,p1->terms =p2->terms ,p2->terms =w; l=p1->nterm ,p1->nterm =p2->nterm ,p2->nterm =l; l=p1->ntermalloc,p1->ntermalloc=p2->ntermalloc,p2->ntermalloc=l; } static void psn_cons_alloc(psn *seq) { seq->cons=(double *)malloc(sizeof(double)*FRAGSIZE_CONS); seq->ncon=0,seq->nconalloc=FRAGSIZE_CONS; } int psn_cons_append(psn *seq,double con) { int ret; if ( seq->cons==NULL ) psn_cons_alloc(seq); if ( seq->ncon+1>seq->nconalloc ) { seq->nconalloc+=FRAGSIZE_CONS; seq->cons=(double *)realloc(seq->cons,sizeof(double)*seq->nconalloc); } ret=seq->ncon; seq->cons[ret]=con; seq->ncon++; return(ret); } static void psn_cons_append_more(psn *seq,double *cons,int n) { while ( n ) { psn_cons_append(seq,*cons); cons++,n--; }; } /*****************************************************************************/ static psnprop* psn_prop_search(psnprop *pl,int major) { for ( ; pl->major ; pl++ ) { if ( pl->major == major ) return(pl); } return(NULL); } static int psn_get_precedency(psnterm *ps1,psnterm *ps2,psnprop *plist) { psnprop *pl1,*pl2; int p1,p2; for ( pl1=pl2=NULL ; plist->major != 0 && (pl1==NULL||pl2==NULL) ; plist++ ) { if ( ps1->major==plist->major ) pl1=plist; if ( ps2->major==plist->major ) pl2=plist; } p1=p2=0; if ( pl1 != NULL ) p1=pl1->precedency; if ( pl2 != NULL ) p2=pl2->precedency; if ( ps1->type==T_FN ) p1=PSN_MAX_PREC; if ( ps2->type==T_FN ) p2=PSN_MAX_PREC; if ( p1==0 || p2==0 ) return(0); if ( p1==p2 ) { if ( p1==PSN_MAX_PREC ) return(1); else if ( pl1==pl2 ) return(pl1->associativity); else return(0); } else return(p1-p2); } psn * psn_conv(psn *chseq,psnprop *plist) { int sp,plevel; psn *ret; psnterm *in,*stack,stack_loc[PSNSTACKBLOCK],*stack_dyn; int stacklen; in=chseq->terms; ret=psn_alloc(); ret->nseq=1; if ( chseq->cons != NULL ) psn_cons_append_more(ret,chseq->cons,chseq->ncon); stacklen=PSNSTACKBLOCK,sp=0; stack_dyn=NULL; stack=stack_loc; plevel=0; while ( in->type ) { if ( in->type==T_CONST || in->type==T_SCONST || in->type==T_VAR ) { psn_append(ret,in,1); } else if ( in->type==T_PAROPEN ) { psncpy(stack+sp,in);sp++,plevel++; } else if ( ( in->type==T_PARCLOSE || in->type==T_SEP ) && plevel>0 ) { sp--; if ( in->type==T_PARCLOSE ) plevel--; while ( stack[sp].type != T_PAROPEN ) { if ( stack[sp].type==T_FN ) stack[sp].type=T_OP; psn_append(ret,stack+sp,1); sp--; }; if ( in->type==T_SEP ) { psncpy(stack+sp,in); stack[sp].type=T_PAROPEN;sp++; } } else if ( in->type==T_SEP && plevel==0 ) { while ( sp ) { sp--; if ( stack[sp].type==T_FN ) stack[sp].type=T_OP; psn_append(ret,stack+sp,1); }; ret->nseq++; } else if ( in->type==T_OP || in->type==T_FN ) { if ( sp==0 ) { psncpy(stack+sp,in);sp++; } else if ( (stack+sp-1)->type==T_PAROPEN ) { psncpy(stack+sp,in);sp++; } else if ( psn_get_precedency(in,stack+sp-1,plist) > 0 ) { psncpy(stack+sp,in);sp++; } else { while ( psn_get_precedency(stack+sp-1,in,plist)>=0 ) { sp--; if ( stack[sp].type==T_FN ) stack[sp].type=T_OP; psn_append(ret,stack+sp,1); if ( sp==0 || stack[sp-1].type==T_PAROPEN ) break; }; psncpy(stack+sp,in);sp++; } } else { psnerrno=PEINVALID; if ( stack_dyn != NULL ) free(stack_dyn); return(NULL); } if ( sp>=stacklen ) { if ( stacklen==PSNSTACKBLOCK ) { stacklen+=PSNSTACKBLOCK; stack_dyn=(psnterm *)malloc(sizeof(psnterm)*stacklen); memcpy(stack_dyn,stack,sizeof(psnterm)*sp); stack=stack_dyn; } else { stacklen+=PSNSTACKBLOCK; stack=(psnterm *)realloc(stack,sizeof(psnterm)*stacklen); stack_dyn=stack; } } in++; }; while ( sp > 0 ) { sp--; if ( stack[sp].type==T_FN ) stack[sp].type=T_OP; psn_append(ret,stack+sp,1); }; if ( stack_dyn != NULL ) free(stack_dyn); psnerrno=PEOK; return(ret); } /*****************************************************************************/ static int is_cchar_start(int c) { if ( ('a'<=c && c<='z')||('A'<=c && c<='Z')|| c=='_' ) return(1); else return(0); } static int is_cchar(int c) { if ( ('a'<=c && c<='z')||('A'<=c && c<='Z')|| c=='_' ||( '0'<=c && c<='9') ) return(1); else return(0); } static char opchars[]="!#$%&*+-/:<=>@^|~"; static int is_opchar(int c) { char *ch; for ( ch=opchars ; *ch ; ch++ ) { if ( c==(*ch) ) return(1); } return(0); } static int is_numchar_start(int c) { if ( ( '0'<=c && c<='9' ) || c=='.' ) return(1); else return(0); } static int is_numchar(int c) { if ( ( '0'<=c && c<='9' ) || c=='.' || c=='e' || c=='E' ) return(1); else return(0); } static int psn_get_symbol_from_symtable (char *wp,int wl,psnsym **symtable, psnsym *found,int max) { int i,nf; for ( i=0,nf=0 ; *symtable != NULL && nfnseq=1; nc=0; for ( ; *str ; str++ ) { if ( *str==32 || *str==10 || *str==13 || *str==9 ) continue; else if ( *str=='(' ) psn_append_term(ret,T_PAROPEN ,0,0,0); else if ( *str==')' ) psn_append_term(ret,T_PARCLOSE,0,0,0); else if ( *str=='{' ) psn_append_term(ret,T_PAROPEN ,1,0,0); else if ( *str=='}' ) psn_append_term(ret,T_PARCLOSE,1,0,0); else if ( *str=='[' ) psn_append_term(ret,T_PAROPEN ,2,0,0); else if ( *str==']' ) psn_append_term(ret,T_PARCLOSE,2,0,0); else if ( *str==',' ) psn_append_term(ret,T_SEP, 0,0,0); else if ( *str==';' ) psn_append_term(ret,T_SEP, 1,0,0); else if ( is_cchar_start(*str) ) { wl=1,wp=str,str++; while ( is_cchar(*str) ) str++,wl++; str--; nf=psn_get_symbol_from_symtable(wp,wl,symtable,found,1); if ( nf==0 ) { psnerrno=PENOTFOUND; return(NULL); } psn_append_term(ret,found[0].type,found[0].major, found[0].minor,0); } else if ( is_opchar(*str) ) { int fprf,finf,fsff,k; wl=1,wp=str,str++; while ( is_opchar(*str) ) str++,wl++; str--; nf=psn_get_symbol_from_symtable(wp,wl,symtable,found,3); if ( nf==0 ) { psnerrno=PENOTFOUND; return(NULL); } fprf=finf=fsff=-1; for ( k=0 ; kncon ; i++ ) { if ( ret->cons[i]==ind ) break; } if ( incon && ret->ncon>0 ) psn_append_term(ret,T_CONST,i,0,0); else { psn_append_term(ret,T_CONST,nc,0,0); psn_cons_append(ret,ind); nc++; } } } else { psnerrno=PEINVALID; return(NULL); /* illegal character */ } }; psnerrno=PEOK; return(ret); } /*****************************************************************************/ static int psn_init_parentheses(psn *pseq) { int k,wk,type,nseq; psnterm *seq; int *stack,stack_local[3*PSNSTACKBLOCK],*stack_dyn,stacklen,sp; seq=pseq->terms; stacklen=3*PSNSTACKBLOCK; stack=stack_local,stack_dyn=NULL; sp=0; nseq=1; for ( k=0 ; seq[k].type ; k++ ) { type=seq[k].type; if ( type==T_PAROPEN ) { stack[sp+0]=1, stack[sp+1]=k; stack[sp+2]=seq[k].major; sp+=3; } else if ( type==T_SEP ) { if ( sp>0 ) { if ( stack[sp-1] != seq[k].major ) return(PEPARSE); stack[sp-3]++; } else nseq++; } else if ( type==T_PARCLOSE ) { if ( sp==0 ) return(PEPARSE); sp-=3; if ( stack[sp+2] != seq[k].major ) return(PEPARSE); wk=stack[sp+1]; if ( k>wk+1 ) seq[wk].minor=seq[k].minor=stack[sp+0]; else seq[wk].minor=seq[k].minor=0; } if ( sp>=stacklen-3 ) { if ( stacklen==3*PSNSTACKBLOCK ) { stacklen+=3*PSNSTACKBLOCK; stack_dyn=(int *)malloc(sizeof(int)*stacklen); memcpy(stack_dyn,stack,sizeof(int)*sp); stack=stack_dyn; } else { stacklen+=3*PSNSTACKBLOCK; stack=(int *)realloc(stack_dyn,sizeof(int)*stacklen); stack_dyn=stack; } } } pseq->nseq=nseq; if ( stack_dyn != NULL ) free(stack_dyn); if ( sp>0 ) return(PEPARSE); else return(0); } static int psn_init_function_arguments(psn *pseq) { int k,narg; psnterm *seq; seq=pseq->terms; for ( k=0 ; seq[k].type ; k++ ) { if ( seq[k].type==T_FN && seq[k+1].type==T_PAROPEN ) { narg=seq[k+1].minor; if ( seq[k].minor < 0 ) seq[k].minor=narg; else if ( seq[k].minor != narg ) return(PEPARSE); else seq[k].minor=narg; } else if ( seq[k].type==T_FN ) seq[k].minor=0; } return(0); } static int psn_init_operators(psn *pseq) { int k,tprev,tfoll,iprf,iinf,isff; int canbe_prefix,canbe_suffix; psnterm *seq; seq=pseq->terms; for ( k=0,tprev=0 ; seq[k].type ; k++ ) { tfoll=seq[k+1].type; if ( seq[k].type==T_OP ) { iprf=seq[k].major, iinf=seq[k].minor, isff=seq[k].cache; if ( tprev==0 || tprev==T_PAROPEN || tprev==T_OP || tprev==T_FN || tprev==T_SEP ) canbe_prefix=1; else canbe_prefix=0; if ( tfoll==0 || tfoll==T_PARCLOSE || tfoll==T_OP || tfoll==T_SEP ) canbe_suffix=1; else canbe_suffix=0; if ( canbe_prefix && (!canbe_suffix) ) seq[k].major=iprf,seq[k].minor=1; else if ( canbe_suffix && (!canbe_prefix) ) seq[k].major=isff,seq[k].minor=1; else if ( (!canbe_prefix) && (!canbe_suffix) ) seq[k].major=iinf,seq[k].minor=2; else return(PEPARSE); if ( seq[k].major < 0 ) return(PEPARSE); else if ( seq[k].major==0 ) /* Remove identity... */ psn_remove(pseq,k,1); } tprev=seq[k].type; }; return(0); } int psn_cache_clear(psn *seq) { psnterm *term; for ( term=seq->terms ; term->type != 0 ; term++ ) { if ( term->type==T_OP || term->type==T_FN ) term->cache=-1; } return(0); } int psn_init(psn *pseq,psnprop *plist) { int k; k=psn_init_parentheses(pseq); if ( k ) return(psnerrno=k); k=psn_init_function_arguments(pseq); if ( k ) return(psnerrno=k); k=psn_init_operators(pseq); if ( k ) return(psnerrno=k); psn_cache_clear(pseq); psnerrno=PEOK; return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int psn_cache_search(int major,psnfunct *flist) { int k; for ( k=0 ; flist[k].major != 0 ; k++ ) { if ( major == flist[k].major ) return(k); } return(-1); } int psn_cache_init(psn *pseq,psnfunct *flist) { psnterm *seq; int k; for ( seq=pseq->terms ; seq->type != 0 ; seq++ ) { if ( seq->type==T_OP || seq->type==T_FN ) { k=psn_cache_search(seq->major,flist); if ( k<0 ) return(psnerrno=PENOTFOUND); seq->cache=k; } } return(psnerrno=0); } /*****************************************************************************/ static char * psn_symtable_search(psnsym **symtable,int major,int t1,int t2) { int i; if ( symtable==NULL ) return(NULL); while ( *symtable != NULL ) { for ( i=0 ; (*symtable)[i].type != 0 ; i++ ) { if ( ( (*symtable)[i].type==t1 || (*symtable)[i].type==t2 ) && (*symtable)[i].major==major ) return((*symtable)[i].name); } symtable++; }; return(NULL); } void psn_fprint(FILE *f,psn *seq,psnsym **symtable) { psnterm *psn; char *name; for ( psn=seq->terms ; psn->type ; psn++ ) { if ( psn->type==T_PAROPEN ) fprintf(f,"(/%d/",psn->minor); else if ( psn->type==T_PARCLOSE ) fprintf(f,")"); else if ( psn->type==T_SEP ) fprintf(f,","); else if ( psn->type==T_CONST ) fprintf(f,"%g",seq->cons[psn->major]); else if ( psn->type==T_SCONST ) fprintf(f,"%g",(double)(psn->major)); else if ( psn->type==T_OP || psn->type==T_FN ) { name=psn_symtable_search(symtable,psn->major,T_OP,T_FN ); if ( name != NULL ) fprintf(f,"[%s]/%d/",name,psn->minor); else fprintf(f,"???"); } else if ( psn->type==T_VAR ) { name=psn_symtable_search(symtable,psn->major,T_VAR,T_VAR); if ( name != NULL ) fprintf(f,"%s",name); else fprintf(f,"???"); } else if ( psn->type==T_STACKVAR ) fprintf(f,"(%d)",psn->major); fprintf(f," "); } } /*****************************************************************************/ int psn_get_nstack(psn *pseq,int *ropt) { int sp,nopt,narg; psnterm *seq; seq=pseq->terms; nopt=0; for ( sp=0 ; seq->type ; seq++ ) { switch( seq->type ) { case T_CONST: case T_SCONST: case T_VAR: sp++; break; case T_STACKVAR: if ( seq->major+1>nopt ) nopt=seq->major+1; sp++; break; case T_OP: case T_FN: narg=seq->minor; if ( spnterm); } int psn_get_nseq(psn *seq) { return(seq->nseq); } int psn_test(psn *pseq) { int nopt,n; n=psn_get_nstack(pseq,&nopt); if ( n<0 ) return(n); if ( n==pseq->nseq+nopt ) return(psnerrno=0); else return(psnerrno=PEPARSE); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int psn_double_calc(psn *pseq,psnfunct *flist,double *result,double *vars) { double stack_automatic[PSNSTACKBLOCK],*stack_dynamic,*stack; int i,nopt,narg,sp; psnterm *seq; int stacklen; stack=stack_automatic; stack_dynamic=NULL; stacklen=PSNSTACKBLOCK; nopt=0;sp=0; for ( seq=pseq->terms ; seq->type ; seq++ ) { switch( seq->type ) { case T_CONST: stack[sp]=pseq->cons[seq->major],sp++; break; case T_VAR: stack[sp]=vars[seq->major],sp++; break; case T_SCONST: stack[sp]=(double)(seq->major),sp++; break; case T_STACKVAR: stack[sp]=stack[seq->major],sp++; if ( seq->major+1>nopt ) nopt=seq->major+1; break; case T_OP: case T_FN: narg=seq->minor; i=seq->cache; if ( i<0 ) { i=psn_cache_search(seq->major,flist); if ( i<0 ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENOTFOUND); } seq->cache=i; } if ( flist[i].funct(stack+sp) ) { if ( stack_dynamic != NULL ) free(stack_dynamic); return(psnerrno=PENUMERICAL); } sp+=1-narg; break; } if ( sp>=stacklen ) { if ( stacklen==PSNSTACKBLOCK ) { int i; stacklen+=PSNSTACKBLOCK; stack_dynamic=(double *)malloc(sizeof(double)*stacklen); for ( i=0 ; i0 ; terms++,n-- ) { if ( terms->type==T_VAR && terms->major==var ) return(1); } return(0); } static psn * psn_diff_int(psn *pseq,psnprop *plist,psndiff *rules, int var,int flags) { psn *ncc,*dcc; psnterm *seq; psnprop *pr; int i,j,k,pn,pd,sp,*pc,stacklen,in,major; short *dr; for ( i=0 ; interm ; i++ ) { if ( pseq->terms[i].type==T_STACKVAR ) { psnerrno=PEOPTIMIZED; return(NULL); } } dcc=psn_alloc(); if ( dcc==NULL ) { psnerrno=PEALLOC; return(NULL); } ncc=psn_alloc(); if ( ncc==NULL ) { psnerrno=PEALLOC; psn_free(dcc); return(NULL); } ncc->nseq=pseq->nseq; if ( pseq->cons != NULL ) psn_cons_append_more(dcc,pseq->cons,pseq->ncon); stacklen=PSNSTACKBLOCK; pc=(int *)malloc(sizeof(int)*4*stacklen); sp=0;pc[0]=pc[1]=pc[2]=pc[3]=0; for ( seq=pseq->terms ; seq->type ; seq++ ) { switch( seq->type ) { case T_CONST: case T_SCONST: case T_VAR: if ( seq->type==T_VAR && var==seq->major ) major=1; else major=0; psn_append_term(dcc,T_SCONST,major,0,0); pd=pc[4*sp];pd++; psn_append(ncc,seq,1); pn=pc[4*sp+2];pn++; pc[4*sp+1]=pc[4*sp+3]=1; sp++; pc[4*sp]=pd,pc[4*sp+2]=pn; pc[4*sp+1]=pc[4*sp+3]=0; break; case T_OP: case T_FN: pr=psn_prop_search(plist,seq->major); if ( pr==NULL ) { psn_free(ncc);psn_free(dcc); psnerrno=PENOTFOUND; return(NULL); } in=pr->argnum; /* number of operands */ for ( i=0 ; rules[i].major != 0 ; i++ ) { if ( rules[i].major==seq->major ) break; } if ( rules[i].major==0 ) { if ( ! flags ) { psn_free(ncc);psn_free(dcc); psnerrno=PENONDIFF; return(NULL); } else dr=NULL; } else dr=rules[i].oplist; /* get differental rule */ pd=pc[4*sp]; if ( dr != NULL ) { i=0; for ( ; *dr ; dr++ ) { if ( *dr>=0 ) { pr=psn_prop_search(plist,*dr); if ( pr==NULL ) { psn_free(ncc);psn_free(dcc); psnerrno=PENOTFOUND; return(NULL); } psn_append_term(dcc,T_OP,*dr,pr->argnum,0); i++; } else if ( -SS_REF+1<=*dr && *dr<=-1 ) { j=(-(*dr))- 0;k=pc[4*(sp-j)+1]; psn_append_inseq(dcc,pc[4*(sp-j)+0],k); i+=k; } else if ( -2*SS_REF+1<=*dr && *dr<=-SS_REF-1 ) { j=(-(*dr))-SS_REF;k=pc[4*(sp-j)+3]; psn_append(dcc,ncc->terms+pc[4*(sp-j)+2],k); i+=k; } else { j=(-(*dr))-2*SS_REF; psn_append_term(dcc,T_SCONST,j,0,0); i++; } } } else { for ( i=0 ; iterms+pc[4*(sp-in+i)+2],k,var) ) { psn_free(ncc);psn_free(dcc); psnerrno=PENONDIFF; return(NULL); } } psn_append_term(dcc,T_SCONST,0,0,0); i=1; } pn=pc[4*sp+2]; psn_append(ncc,seq,1); sp-=in; psn_remove(dcc,pc[4*sp],pd-pc[4*sp]); pc[4*sp+1]=i; pc[4*sp+3]++; for ( i=1 ; i=stacklen-2 ) { stacklen+=PSNSTACKBLOCK; pc=(int *)realloc(pc,sizeof(int)*4*stacklen); } } psn_free(ncc); psn_memory_compact(dcc); dcc->nseq=pseq->nseq; psn_cache_clear(dcc); free(pc); psnerrno=PEOK; return(dcc); } psn * psn_diff(psn *pseq,psnprop *plist,psndiff *rules,int var) { psn *diff; diff=psn_diff_int(pseq,plist,rules,var,0); return(diff); } /*****************************************************************************/ static int psn_int_cmp(psn *seq,int p1,int p2,int n) { psnterm *t1,*t2; for ( t1=seq->terms+p1,t2=seq->terms+p2 ; n>0 ; n--,t1++,t2++ ) { if ( t1->type != t2->type || t1->major != t2->major ) return(1); }; return(0); } static int psn_int_cpy(psn *seq,int p1,int p2,int n) { memmove(seq->terms+p1,seq->terms+p2,n*sizeof(psnterm)); return(0); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int psn_optimize(psn *pseq) { psnterm *wseq; psn *ncc; int i,j,k,pn,ps,sp,stacklen,in,w; istack *stack; int nopt,ofound; /* number of optimized elements... */ ncc=psn_alloc(); if ( ncc==NULL ) return(psnerrno=PEALLOC); ncc->nseq=pseq->nseq; stacklen=PSNSTACKBLOCK; stack=(istack *)malloc(sizeof(istack)*stacklen); sp=0; stack[0].offset=0; stack[0].length=0; for ( wseq=pseq->terms ; wseq->type ; wseq++ ) /* already optimized! */ { if ( wseq->type==T_STACKVAR ) return(psnerrno=0); } nopt=0; for ( wseq=pseq->terms ; wseq->type ; wseq++ ) { switch( wseq->type ) { case T_CONST: case T_SCONST: case T_VAR: pn=stack[sp].offset; psn_append(ncc,wseq,1); pn++; stack[sp].length=1; sp++; stack[sp].offset=pn; stack[sp].length=0; break; case T_OP: case T_FN: in=wseq->minor; pn=stack[sp].offset; psn_append(ncc,wseq,1); sp-=in; stack[sp].length++; for ( i=1 ; i1 ) { for ( i=0 ; i search! */ { for ( j=stack[nopt].offset,ofound=0 ; j+ps<=stack[sp].offset ; j++ ) { if ( psn_int_cmp(ncc,j,stack[sp].offset,ps) != 0 ) continue; if ( ! ofound ) { w=stack[nopt].offset; psn_insert(ncc,stack[nopt].offset,ps); for ( k=nopt ; k<=sp ; k++ ) { stack[k].offset+=ps; } j+=ps; memmove(stack+nopt+1,stack+nopt, sizeof(istack)*(sp-nopt+1)); sp++; if ( sp>=stacklen-2 ) { stacklen+=PSNSTACKBLOCK; stack=(istack *)realloc(stack, sizeof(istack)*stacklen); } stack[nopt].offset=w; stack[nopt].length=ps; psn_int_cpy(ncc,stack[nopt].offset, stack[sp].offset,ps); ofound=1,nopt++; } psn_remove(ncc,j,ps-1); for ( k=0 ; k<=sp ; k++ ) { if ( stack[k].offset>j ) stack[k].offset-=ps-1; if ( stack[k].offset<=j && jterms[j].type=T_STACKVAR; ncc->terms[j].major=nopt-1; ncc->terms[j].minor=0; ncc->terms[j].cache=-1; } if ( ofound ) { stack[sp].length=1; psn_remove(ncc,stack[sp].offset,ps); psn_append_term(ncc,T_STACKVAR,nopt-1,0,-1); } } } sp++; stack[sp].offset=stack[sp-1].offset+stack[sp-1].length; stack[sp].length=0; break; } if ( sp>=stacklen-2 ) { stacklen+=PSNSTACKBLOCK; stack=(istack *)realloc(stack,sizeof(istack)*stacklen); } } psn_swap_sequences(ncc,pseq); psn_free(ncc); free(stack); return(psnerrno=0); } /*****************************************************************************/ static int psn_search_variable_code(int *varlist,int in,int major) { if ( varlist==NULL ) { if ( majornseq=pseq->nseq; if ( pseq->cons != NULL ) psn_cons_append_more(ncc,pseq->cons,pseq->ncon); stacklen=PSNSTACKBLOCK; stack=(istack *)malloc(sizeof(istack)*stacklen); sp=0; stack[0].offset=0; stack[0].length=0; for ( wseq=pseq->terms ; wseq->type ; wseq++ ) /* already optimized */ { if ( wseq->type==T_STACKVAR ) { psn_free(ncc); psnerrno=PEOPTIMIZED; return(NULL); } } for ( wseq=pseq->terms ; wseq->type ; wseq++ ) { switch( wseq->type ) { case T_CONST: case T_SCONST: case T_VAR: pn=stack[sp].offset; psn_append(ncc,wseq,1); pn++; stack[sp].length=1; sp++; stack[sp].offset=pn; stack[sp].length=0; break; case T_OP: case T_FN: in=wseq->minor; if ( spmajor == major ) /* replace by 'replacement' */ { ps=0; for ( wrep=replacement->terms ; wrep->type ; wrep++ ) { if ( wrep->type==T_VAR && (k=psn_search_variable_code(varlist,in,wrep->major)) >=0 ) { k+=sp-in; psn_append_inseq(ncc,stack[k].offset,stack[k].length); ps+=stack[k].length; } else if ( wrep->type != T_CONST ) { psn_append(ncc,wrep,1); ps++; } else if ( replacement->cons==NULL || wrep->major >= replacement->ncon ) { free(stack); psn_free(ncc); psnerrno=PEINVALID; return(NULL); } else { d=replacement->cons[wrep->major]; for ( i=0 ; incon ; i++ ) { if ( ncc->cons[i]==d ) break; } if ( i >= ncc->ncon ) { i=ncc->ncon; psn_cons_append(ncc,d); } psn_append_term(ncc,T_CONST,i,0,0); ps++; } } rs=0; for ( i=0 ; i=stacklen-2 ) { stacklen+=PSNSTACKBLOCK; stack=(istack *)realloc(stack,sizeof(istack)*stacklen); } } free(stack); psnerrno=0; return(ncc); } /*****************************************************************************/ psn * psn_duplicate(psn *pseq) { psn *ret; ret=psn_alloc(); ret->nseq=pseq->nseq; if ( pseq->cons != NULL ) psn_cons_append_more(ret,pseq->cons,pseq->ncon); psn_append(ret,pseq->terms,pseq->nterm); return(ret); } /*****************************************************************************/ int psn_concate(psn *pseq,psn *ps2) { int i,type,major,minor,cache; psnterm *seq; for ( i=0 ; interm ; i++ ) { if ( pseq->terms[i].type==T_STACKVAR ) return(psnerrno=PEOPTIMIZED); } for ( i=0 ; interm ; i++ ) { if ( ps2->terms[i].type==T_STACKVAR ) return(psnerrno=PEOPTIMIZED); } for ( seq=ps2->terms ; seq->type ; seq++ ) { type=seq->type; major=seq->major; minor=seq->minor; cache=seq->cache; if ( type==T_CONST ) { for ( i=0 ; incon ; i++ ) { if ( pseq->cons[i]==ps2->cons[major] ) break; } if ( incon && pseq->ncon>0 ) { major=i; } else { psn_cons_append(pseq,ps2->cons[major]); major=pseq->ncon-1; } } psn_append_term(pseq,type,major,minor,cache); } pseq->nseq+=ps2->nseq; return(psnerrno=0); } /*****************************************************************************/ static psn *psn_subextract(psn *pseq,int **rpc,int *rnopt) { psnterm *wseq; psn *ncc; int i,pn,sp,in,nopt,*pc,stacklen; ncc=psn_alloc(); if ( ncc==NULL ) { psnerrno=PEALLOC; return(NULL); } if ( pseq->cons != NULL ) psn_cons_append_more(ncc,pseq->cons,pseq->ncon); pc=*rpc; stacklen=PSNSTACKBLOCK; sp=0;pc[0]=pc[1]=0; nopt=0; for ( wseq=pseq->terms ; wseq->type ; wseq++ ) { switch( wseq->type ) { case T_CONST: case T_SCONST: case T_VAR: pn=pc[2*sp]; psn_append(ncc,wseq,1); pn++; pc[2*sp+1]=1; sp++; pc[2*sp]=pn; pc[2*sp+1]=0; break; case T_STACKVAR: i=wseq->major; psn_append_inseq(ncc,pc[2*i],pc[2*i+1]); if ( i+1>nopt ) nopt=i+1; pc[2*sp+1]=pc[2*i+1]; sp++; pc[2*sp]=pc[2*(sp-1)]+pc[2*(sp-1)+1]; pc[2*sp+1]=0; break; case T_OP: case T_FN: in=wseq->minor; pn=pc[2*sp]; psn_append(ncc,wseq,1); sp-=in; pc[2*sp+1]++; for ( i=1 ; i=stacklen-2 ) { stacklen+=PSNSTACKBLOCK; pc=(int *)realloc(pc,sizeof(int)*2*stacklen); } } *rnopt=nopt; *rpc=pc; return(ncc); } psn *psn_extract(psn *pseq,int n) { int i,nopt; psn *ncc; int *pc; pc=(int *)malloc(sizeof(int)*2*PSNSTACKBLOCK); if ( n>=pseq->nseq ) { psnerrno=PEINVALID; return(NULL); } ncc=psn_subextract(pseq,&pc,&nopt); if ( ncc==NULL ) { /* psnerrno=PE... */ /*(already set by psn_subextract())*/ return(NULL); } i=n+nopt; psn_remove(ncc,pc[2*(i+1)],ncc->nterm-pc[2*(i+1)]); psn_remove(ncc,0,pc[2*n]); ncc->nseq=1; free(pc); return(ncc); } psn *psn_full_extract(psn *pseq) { int nopt; psn *ncc; int *pc; pc=(int *)malloc(sizeof(int)*2*PSNSTACKBLOCK); ncc=psn_subextract(pseq,&pc,&nopt); if ( ncc==NULL ) { /* psnerrno=PE... */ /*(already set by psn_subextract())*/ return(NULL); } psn_remove(ncc,0,pc[2*nopt]); ncc->nseq=pseq->nseq; free(pc); return(ncc); } /*****************************************************************************/ typedef struct { char *string; int precedency; int affix; } psnstringstack; static int psn_convert_add_char(char **ret,int *rp,int *rsize,int ch) { (*ret)[*rp]=ch; (*rp)++; if ( (*rp)>=(*rsize) ) *ret=(char *)realloc(*ret,(*rsize)+BLOCKSIZE), *rsize+=BLOCKSIZE; return(0); } static int psn_convert_add_string(char **ret,int *rp,int *rsize,char *str) { for ( ; *str ; str++ ) psn_convert_add_char(ret,rp,rsize,*str); return(0); } static char *psn_convert_replace_single(char *str,char *rep) { char *ret; int rsize,rp; rsize=BLOCKSIZE,rp=0; ret=(char *)malloc(rsize); while ( *str ) { if ( *str != '#' ) { psn_convert_add_char(&ret,&rp,&rsize,*str); str++; } else { str++; if ( *str != '0' ) { psn_convert_add_char(&ret,&rp,&rsize,*str); str++; } else { psn_convert_add_string(&ret,&rp,&rsize,rep); str++; } } }; psn_convert_add_char(&ret,&rp,&rsize,0); return(ret); } static char *psn_convert_replace_more(char *str,psnstringstack *first, char *parexpr,int precedency) { char *ret,*wexpr; int rsize,rp,to_paren,to_paren_equ,n; int is_term_first,is_term_last,affix; rsize=BLOCKSIZE,rp=0; ret=(char *)malloc(rsize); is_term_first=1; while ( *str ) { if ( *str != '#' ) { psn_convert_add_char(&ret,&rp,&rsize,*str); str++; } else if ( *(str+1) == '#' ) { psn_convert_add_char(&ret,&rp,&rsize,'#'); str++;str++; } else { str++;to_paren=0,to_paren_equ=0; if ( *str == '(' ) to_paren=1,str++; else if ( *str == '[' ) to_paren=1,to_paren_equ=1,str++; n=*str-'1',str++; if ( n<0 || n>8 ) { free(ret); psnerrno=PEINVALID; return(NULL); } if ( to_paren ) { if ( ( *str != ')' && ! to_paren_equ ) || ( *str != ']' && to_paren_equ ) ) { free(ret); psnerrno=PEINVALID; return(NULL); } str++; } if ( *str==0 ) is_term_last=1; else is_term_last=0; affix=first[n].affix; if ( to_paren && ( ( first[n].precedency < precedency && ! to_paren_equ ) || ( first[n].precedency <= precedency && to_paren_equ ) || ( affix==TO_PREFIX && ! is_term_first ) || ( affix==TO_SUFFIX && ! is_term_last ) ) ) { wexpr=psn_convert_replace_single(parexpr, first[n].string); psn_convert_add_string(&ret,&rp,&rsize,wexpr); free(wexpr); } else psn_convert_add_string(&ret,&rp,&rsize,first[n].string); } is_term_first=0; }; psn_convert_add_char(&ret,&rp,&rsize,0); return(ret); } static char *psn_convert_to_const(double d,char *dformat) { char buff[128],*ret; if ( dformat==NULL ) sprintf(buff,"%g",d); else sprintf(buff,dformat,d); ret=(char *)malloc(strlen(buff)+1); strcpy(ret,buff); return(ret); } static char *psn_convert_to_symbol(int major,psnsym **symtable) { char *name,*ret; name=psn_symtable_search(symtable,major,T_VAR,T_VAR); if ( name==NULL ) return(NULL); ret=(char *)malloc(strlen(name)+1); strcpy(ret,name); return(ret); } static int psn_convert_stack_cleanup(psnstringstack *chstack,int n) { while ( n ) { free(chstack->string); n--,chstack++; }; return(0); } char *psn_convert_symbolic(psn *seq,psnprop *plist,psnsymeval *syt, psnsym **sym,char *dformat) { psnterm *wseq; psnprop *wp; int sp,argnum,i,stacklen; psnsymeval *wsy,*sypar; char *wstr,*ret; double dd; psnstringstack *chstack; if ( seq->nseq != 1 ) { psnerrno=PEMULTI; return(NULL); } for ( wseq=seq->terms ; wseq->type ; wseq++ ) { if ( wseq->type==T_STACKVAR ) { psnerrno=PEOPTIMIZED; return(NULL); } } for ( i=0,sypar=NULL ; ! ( syt[i].major==0 && syt[i].string==NULL ) ; i++ ) { if ( syt[i].major==0 ) { sypar=&syt[i]; break; } } if ( sypar==NULL ) { psnerrno=PENOTFOUND; return(NULL); } stacklen=PSNSTACKBLOCK; chstack=(psnstringstack *)malloc(sizeof(psnstringstack)*stacklen); sp=0; for ( wseq=seq->terms ; wseq->type ; wseq++ ) { switch ( wseq->type ) { case T_VAR: wstr=psn_convert_to_symbol(wseq->major,sym); if ( wstr==NULL ) { psn_convert_stack_cleanup(chstack,sp); free(chstack); psnerrno=PENOTFOUND; return(NULL); } chstack[sp].string=wstr; chstack[sp].precedency=PSN_MAX_PREC; chstack[sp].affix=0; sp++; break; case T_SCONST: case T_CONST: if ( wseq->type==T_SCONST ) dd=(double)wseq->major; else dd=seq->cons[wseq->major]; wstr=psn_convert_to_const(dd,dformat); if ( dd<0.0 ) { chstack[sp].string= psn_convert_replace_single(sypar->string,wstr); free(wstr); } else chstack[sp].string=wstr; chstack[sp].precedency=PSN_MAX_PREC; chstack[sp].affix=0; sp++; break; case T_OP: case T_FN: wp=psn_prop_search(plist,wseq->major); if ( wp==NULL ) { psn_convert_stack_cleanup(chstack,sp); free(chstack); psnerrno=PENOTFOUND; return(NULL); } argnum=wp->argnum; /* Currently, functions with arbitrary number of arguments */ /* (argnum<0) are not allowed here: the expected */ /* number of arguments 'wp->argnum' should be equal to */ /* the number of arguments stored in the auxiliary field */ /* 'wseq->minor'. However, if such desired number of */ /* arguments cannot be found in the stack (thus, sp sp || wseq->minor != argnum ) { psn_convert_stack_cleanup(chstack,sp); free(chstack); psnerrno=PEINVALID; return(NULL); } for ( wsy=syt ; ! ( wsy->major == 0 && wsy->string == NULL ) ; wsy++ ) { if ( wsy->major == wseq->major ) break; } if ( wsy->major == 0 && wsy->string == NULL ) { psn_convert_stack_cleanup(chstack,sp); free(chstack); psnerrno=PENOTFOUND; return(NULL); } /* major=wsy->major; */ wstr=psn_convert_replace_more(wsy->string,&chstack[sp-argnum], sypar->string,wp->precedency); if ( wstr==NULL ) { psn_convert_stack_cleanup(chstack,sp); free(chstack); psnerrno=PENOTFOUND; return(NULL); } for ( i=0 ; istrength ) { chstack[sp].precedency=PSN_MAX_PREC, chstack[sp].affix=0; } else { chstack[sp].precedency=wp->precedency; chstack[sp].affix=wsy->affixation; } sp++; break; default: psn_convert_stack_cleanup(chstack,sp); free(chstack); psnerrno=PEINVALID; return(NULL); } if ( sp>=stacklen ) { stacklen+=PSNSTACKBLOCK; chstack=(psnstringstack *)realloc(chstack, sizeof(psnstringstack)*stacklen); } } if ( sp != 1 ) { psn_convert_stack_cleanup(chstack,sp); psnerrno=PEINVALID; free(chstack); return(NULL); } ret=chstack[0].string; free(chstack); return ( ret ); } /*****************************************************************************/ typedef struct { int op; int last; int prev; int block; int size; } psntree; typedef struct { int major; short *pre; int prelen; short *post; int postlen; psntree *tree; int treepos; } psnsimpcache; typedef struct { psnsimpcache *psc; int ns; psntree *alltree; } psnsimpinfo; typedef struct { int block; int size; } psnsimpexp; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int psn_build_simp_tree(short *srule,psntree *tree,psnprop *plist) { short *wseq; psntree *wt; psnprop *wp; int *opstack,sp,stacklen; int i,j,k,l,n,argnum,size; stacklen=PSNSTACKBLOCK; opstack=(int *)malloc(sizeof(int)*stacklen); sp=0; for ( wseq=srule,n=0,wt=tree ; *wseq ; wseq++,n++,wt++ ) { if ( *wseq < 0 ) { opstack[sp]=n; sp++; wt->op=-1; wt->last=-1; wt->prev=-1; wt->block=n; wt->size=1; } else { wp=psn_prop_search(plist,*wseq); if ( wp==NULL ) { free(opstack); return(1); } argnum=wp->argnum; size=1; if ( argnum>0 ) { k=wt->last=opstack[sp-1]; for ( i=argnum-1,j=sp-1 ; i>0 ; i--,j-- ) { l=tree[k].prev=opstack[j-1]; tree[k].op=n; size+=tree[k].size; k=l; } tree[k].prev=-1; tree[k].op=n; size+=tree[k].size; wt->block=tree[k].block; } else { wt->block=n; wt->last=-1; } wt->size=size; wt->op=-1; wt->prev=-1; sp-=argnum; opstack[sp]=n; sp++; } if ( sp>=stacklen ) { stacklen+=PSNSTACKBLOCK; opstack=(int *)realloc(opstack,sizeof(int)*stacklen); } } free(opstack); return(0); } static int psn_build_simp_info(psnsimpinfo *psi,short **rules,psnprop *plist) { int i,j,k,ns; short *rlist; psnsimpcache *psc; psntree *alltree; int alltreelen; for ( ns=0 ; rules[ns] != NULL ; ns++ ) ; psc=(psnsimpcache *)malloc(sizeof(psnsimpcache)*ns); alltree=NULL; alltreelen=0; for ( i=0 ; ins=ns; psi->psc=psc; psi->alltree=alltree; return(0); } static int psn_drop_simp_info(psnsimpinfo *psi) { if ( psi->psc != NULL ) free(psi->psc); if ( psi->alltree != NULL ) free(psi->alltree); return(0); } static int psn_build_tree(psn *seq,psntree *tree) { psnterm *wseq; psntree *wt; int *opstack,sp,stacklen; int i,j,k,l,n,argnum,size; stacklen=PSNSTACKBLOCK; opstack=(int *)malloc(sizeof(int)*stacklen); sp=0; for ( wseq=seq->terms,n=0,wt=tree ; wseq->type ; wseq++,n++,wt++ ) { switch ( wseq->type ) { case T_VAR: case T_CONST: case T_SCONST: opstack[sp]=n; sp++; wt->op=-1; wt->last=-1; wt->prev=-1; wt->block=n; wt->size=1; break; case T_FN : case T_OP: argnum=wseq->minor; size=1; if ( argnum>0 ) { k=wt->last=opstack[sp-1]; for ( i=argnum-1,j=sp-1 ; i>0 ; i--,j-- ) { l=tree[k].prev=opstack[j-1]; tree[k].op=n; size+=tree[k].size; k=l; } tree[k].prev=-1; tree[k].op=n; size+=tree[k].size; wt->block=tree[k].block; } else { wt->block=n; wt->last=-1; } wt->size=size; wt->op=-1; wt->prev=-1; sp-=argnum; opstack[sp]=n; sp++; break; } if ( sp>=stacklen ) { stacklen+=PSNSTACKBLOCK; opstack=(int *)realloc(opstack,sizeof(int)*stacklen); } } free(opstack); return(0); } static int psn_simp_compare(psn *seq,psntree *tree,int t, psnsimpexp *psex, short *pre,int cp,psntree *stree) { int w,k,wt,ws; psnterm *terms; terms=seq->terms; w=pre[cp]; if ( w>0 ) { if ( ! ( terms[t].type == T_OP || terms[t].type == T_FN ) ) return(1); if ( terms[t].major != w ) return(1); wt=tree[t].last, ws=stree[cp].last; while ( ws>=0 ) { if ( wt<0 ) return(1); k=psn_simp_compare(seq,tree,wt,psex,pre,ws,stree); if ( k ) return(1); wt=tree [wt].prev; ws=stree[ws].prev; }; return(0); } else if ( w<=-2*SS_REF ) { int major; major=terms[t].major; w=-2*SS_REF-w; if ( terms[t].type==T_SCONST && major==w ) return(0); else if ( terms[t].type==T_CONST && seq->cons[major]==(double)w ) return(0); else return(1); } else if ( w<0 ) { w=(-w)-1; if ( psex[w].block<0 ) { psex[w].block=tree[t].block; psex[w].size =tree[t].size ; return(0); } else { int block,size,wblock,wsize; block=psex[w].block, size =psex[w].size; wblock=tree[t].block, wsize =tree[t].size; if ( size != wsize ) return(1); k=psn_int_cmp(seq,block,wblock,size); return(k); } } else /* w==0, this should not happen. */ return(-1); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifdef __DEBUG static void __psn_print_tree(psntree *tree,int n) { int i; FILE *fw; fw=stderr; fprintf(fw,"op: "); for ( i=0 ; iterms ; wterm->type ; wterm++ ) { if ( wterm->type==T_STACKVAR ) return(psnerrno=PEOPTIMIZED); } k=psn_build_simp_info(psi,rules,plist); if ( k ) return(psnerrno=PEINVALID); wtreelen=seq->nterm; wtree=(psntree *)malloc(sizeof(psntree)*wtreelen); psn_build_tree(seq,wtree); #ifdef __DEBUG __psn_print_tree(wtree,wtreelen); #endif for ( t=0 ; seq->terms[t].type ; t++ ) { if ( ! ( seq->terms[t].type==T_OP || seq->terms[t].type==T_FN ) ) continue; if ( seq->terms[t].minor>0 && flist != NULL ) { int is_all_const; double *cnst,dret; short sret; is_all_const=1; for ( j=wtree[t].last ; j>=0 && is_all_const; j=wtree[j].prev ) { if ( ! ( wtree[j].size==1 && ( seq->terms[j].type==T_SCONST || seq->terms[j].type==T_CONST ) ) ) is_all_const=0; } if ( is_all_const ) /* All operands are constant... */ { argnum=seq->terms[t].minor; cnst=consstack; t-=argnum; for ( i=0 ; iterms[t+i].major; if ( seq->terms[t+i].type==T_SCONST ) cnst[i]=(double)major; else cnst[i]=seq->cons[major]; } i=psn_cache_search(seq->terms[t+argnum].major,flist); if ( i<0 ) { free(wtree); psn_drop_simp_info(psi); return(psnerrno=PENOTFOUND); } k=flist[i].funct(cnst+argnum); if ( k ) { free(wtree); psn_drop_simp_info(psi); return(psnerrno=PENUMERICAL); } dret=cnst[0];sret=(short)dret; psn_remove(seq,t,argnum); if ( dret != (double)sret ) { major=psn_cons_append(seq,dret); seq->terms[t].type =T_CONST; seq->terms[t].major=major; } else { seq->terms[t].type =T_SCONST; seq->terms[t].major=sret; } seq->terms[t].minor=0; seq->terms[t].cache=0; psn_build_tree(seq,wtree); continue; } } major=seq->terms[t].major; for ( i=0,rfound=-1 ; ins && rfound<0 ; i++ ) { if ( major != psi->psc[i].major ) continue; for ( j=0 ; j<2*SS_REF ; j++ ) { psex[j].block=-1; psex[j].size =-1; } if ( ! psn_simp_compare(seq,wtree,t,psex, psi->psc[i].pre,psi->psc[i].prelen-1,psi->psc[i].tree) ) rfound=i; } if ( rfound < 0 ) continue; if ( psi->psc[rfound].postlen==0 ) { free(wtree); psn_drop_simp_info(psi); return(psnerrno=PEANALYTICAL); } #ifdef __DEBUG fprintf(stderr,"t=%d, rfound=%d\n",t,rfound); #endif post=psi->psc[rfound].post; isize=0; osize =wtree[t].size; oblock=wtree[t].block; olen=seq->nterm; for ( ws=post ; *ws ; ws++ ) { w=(*ws); if ( w>0 ) { major=w; wp=psn_prop_search(plist,major); psn_append_term(seq,T_OP,major,wp->argnum,-1); isize++; } else if ( w<=-(2*SS_REF) ) { major=-w-(2*SS_REF); psn_append_term(seq,T_SCONST,major,0,0); isize++; } else if ( w<0 ) { j=-w-1; psn_append_inseq(seq,psex[j].block,psex[j].size); isize+=psex[j].size; } } #ifdef __DEBUG fprintf(stderr, "oblock=%d, osize=%d, olen=%d, isize=%d\n", oblock,osize,olen,isize); #endif if ( isize>osize ) { psn_insert(seq,oblock,isize-osize); olen+=isize-osize; osize=isize; } psn_int_cpy(seq,oblock,olen,isize); psn_remove(seq,olen,isize); if ( osize>isize ) { psn_remove(seq,oblock+isize,osize-isize); } if ( seq->nterm > wtreelen ) { wtreelen=seq->nterm; wtree=(psntree *)realloc(wtree,sizeof(psntree)*wtreelen); } psn_build_tree(seq,wtree); t=oblock-1; } free(wtree); psn_drop_simp_info(psi); psn_cache_clear(seq); return(psnerrno=0); } /*****************************************************************************/ int psn_register_function(psnsym **syms,psnprop **props, psnfunct **functs,psndiff **diffs,psnsymeval **symevals, int major,char *name,int argnum,int (*funct)(double *), short *diffrule,char *symevalstr) { int c; psnsym *wsym; psnprop *wprop; psnfunct *wfunct; psndiff *wdiff; psnsymeval *wsymeval; /* fprintf(stderr,"psn_register_function(): registering something with major=%d\n",major); */ if ( props==NULL ) return(1); if ( syms != NULL && name != NULL ) { if ( *syms==NULL ) c=0; else { for ( c=0 ; (*syms)[c].type>0 ; ) c++; } *syms=(psnsym *)realloc(*syms,sizeof(psnsym)*(c+2)); wsym=(*syms)+c; wsym->type=T_FN; wsym->major=major; wsym->name=name; wsym->minor=argnum; memset((*syms)+c+1,0,sizeof(psnsym)); } if ( *props==NULL ) c=0; else { for ( c=0 ; (*props)[c].major>0 ; ) c++; } *props=(psnprop *)realloc(*props,sizeof(psnprop)*(c+2)); wprop=(*props)+c; wprop->major=major; wprop->argnum=argnum; wprop->precedency=0; wprop->associativity=0; memset((*props)+c+1,0,sizeof(psnprop)); if ( functs != NULL && funct != NULL ) { if ( *functs==NULL ) c=0; else { for ( c=0 ; (*functs)[c].major>0 ; ) c++; } *functs=(psnfunct *)realloc(*functs,sizeof(psnfunct)*(c+2)); wfunct=(*functs)+c; wfunct->major=major; wfunct->funct=funct; memset((*functs)+c+1,0,sizeof(psnfunct)); } if ( diffs != NULL && diffrule != NULL ) { if ( *diffs==NULL ) c=0; else { for ( c=0 ; (*diffs)[c].major>0 ; ) c++; } *diffs=(psndiff *)realloc(*diffs,sizeof(psndiff)*(c+2)); wdiff=(*diffs)+c; wdiff->major=major; wdiff->oplist=diffrule; memset((*diffs)+c+1,0,sizeof(psndiff)); } if ( symevals != NULL && symevalstr != NULL ) { if ( *symevals==NULL ) c=0; else { for ( c=0 ; (*symevals)[c].major>0 ; ) c++; } *symevals=(psnsymeval *)realloc(*symevals,sizeof(psnsymeval)*(c+2)); wsymeval=(*symevals)+c; wsymeval->major=major; wsymeval->string=symevalstr; wsymeval->strength=0; wsymeval->affixation=0; memset((*symevals)+c+1,0,sizeof(psnsymeval)); } /* fprintf(stderr,"psn_register_function(): registering something with major=%d\n",major); */ return(0); } /*****************************************************************************/ psn *psn_diff_simplify(psn *seq,psnprop *plist,psndiff *dlist, short **slist,psnfunct *flist,int var) { psn *diff,*dup; int ret; if ( slist != NULL ) { dup=psn_duplicate(seq); ret=psn_simplify(dup,slist,plist,flist); if ( ret || psn_test(dup) ) { psn_free(dup); return(NULL); } diff=psn_diff_int(dup,plist,dlist,var,1); psn_free(dup); } else diff=psn_diff_int(seq,plist,dlist,var,1); if ( diff==NULL ) return(NULL); /* psnerrno set by psn_diff(); */ if ( psn_test(diff) ) { psn_free(diff); return(NULL); /* psnerrno set by psn_diff(); */ } if ( slist != NULL ) { ret=psn_simplify(diff,slist,plist,flist); if ( ret || psn_test(diff) ) { psn_free(diff); return(NULL); /* psnerrno set by psn_diff(); */ } } psnerrno=PEOK; return(diff); } /*****************************************************************************/ int * psn_argument_chain(psn *pseq) { int stack_automatic[PSNSTACKBLOCK],*stack_dynamic,*stack; int i,j,narg,sp; psnterm *term; int *chain; int stacklen,chainlen; stack=stack_automatic; stack_dynamic=NULL; stacklen=PSNSTACKBLOCK; chainlen=PSNSTACKBLOCK; chain=(int *)malloc(sizeof(int)*chainlen); sp=0; for ( term=pseq->terms,i=0 ; term->type ; term++,i++ ) { chain[i]=-1; switch( term->type ) { case T_CONST: case T_VAR: case T_SCONST: case T_STACKVAR: stack[sp]=i,sp++; break; case T_OP: case T_FN: narg=term->minor; if ( sp=chainlen ) { chainlen+=PSNSTACKBLOCK; chain=(int *)realloc(chain,sizeof(int)*chainlen); } if ( sp>=stacklen ) { if ( stacklen==PSNSTACKBLOCK ) { int i; stacklen+=PSNSTACKBLOCK; stack_dynamic=(int *)malloc(sizeof(int)*stacklen); for ( i=0 ; i. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and apal@szofi.net $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do $0: have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='fitsh' PACKAGE_TARNAME='fitsh' PACKAGE_VERSION='0.9.2' PACKAGE_STRING='fitsh 0.9.2' PACKAGE_BUGREPORT='apal@szofi.net' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS FITSH_RELEASE FITSH_VERSION PAPER_HEIGHT PAPER_WIDTH PAPERSIZE DVIPS MAN GZIP ROFF HELP2MAN DPKG_DEB DEB_ARCH DEB_VERSION DLLIB DLDYN DLSWC DLEXT INSTALL RANLIB LD AR ac_prog_gzip ac_prog_dvips ac_prog_man EGREP GREP CPP ac_prog_install ac_prog_ranlib ac_prog_ld ac_prog_ar OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dynamic_extensions ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures fitsh 0.9.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/fitsh] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of fitsh 0.9.2:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-dynamic-extensions `lfit` may use dynamic extensions at run-time (default: yes) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF fitsh configure 0.9.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ----------------------------- ## ## Report this to apal@szofi.net ## ## ----------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by fitsh $as_me 0.9.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu RELEASE_DATE=2016.09.23 ############################################################################### # =========================================================================== # http://www.nongnu.org/autoconf-archive/ax_cflags_gcc_option.html # =========================================================================== # # SYNOPSIS # # AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) # # DESCRIPTION # # AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like # "checking CFLAGS for gcc -fvomit-frame ... yes" and adds the optionflag # to CFLAGS if it is understood. You can override the shellvar-default of # CFLAGS of course. The order of arguments stems from the explicit macros # like AX_CFLAGS_WARN_ALL. # # The cousin AX_CXXFLAGS_GCC_OPTION would check for an option to add to # CXXFLAGS - and it uses the autoconf setup for C++ instead of C (since it # is possible to use different compilers for C and C++). # # The macro is a lot simpler than any special AX_CFLAGS_* macro (or # ac_cxx_rtti.m4 macro) but allows to check for arbitrary options. # However, if you use this macro in a few places, it would be great if you # would make up a new function-macro and submit it to the ac-archive. # # - $1 option-to-check-for : required ("-option" as non-value) # - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the other case) # - $3 action-if-found : add value to shellvariable # - $4 action-if-not-found : nothing # # Note: in earlier versions, $1-$2 were swapped. We try to detect the # situation and accept a $2=~/-/ as being the old option-to-check-for. # # There are other variants that emerged from the original macro variant # which did just test an option to be possibly added. However, some # compilers accept an option silently, or possibly for just another option # that was not intended. Therefore, we have to do a generic test for a # compiler family. For gcc we check "-pedantic" being accepted which is # also understood by compilers who just want to be compatible with gcc # even when not being made from gcc sources. # # See also: AX_CFLAGS_SUN_OPTION, AX_CFLAGS_HPUX_OPTION, # AX_CFLAGS_AIX_OPTION, and AX_CFLAGS_IRIX_OPTION. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # # 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 2 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 . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. ############################################################################### # our default $(CFLAGS) are: if test -n "$CFLAGS" ; then cflags_default=no elif test "${ac_cv_env_host_alias_value}" == "win32" ; then HOST=win32 CFLAGS="-Wall -pedantic -O3 -Wno-strict-aliasing -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHOST_WIN32" cflags_default=yes elif test "${ac_cv_env_host_alias_value}" == "win64" ; then HOST=win64 CFLAGS="-Wall -pedantic -O3 -Wno-strict-aliasing -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHOST_WIN32 -DHOST_WIN64" cflags_default=yes elif test "${CC}" == "tcc"; then CFLAGS="-Wall -pedantic -O3 -Wno-strict-aliasing -fPIC -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE" cflags_default=yes else CFLAGS="-Wall -pedantic -ansi -O3 -Wno-strict-aliasing -fPIC -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE" cflags_default=yes fi # some additional: CFLAGS="${CFLAGS} -D_FITSH_SOURCE" dynamic_extensions=yes # Check whether --enable-dynamic-extensions was given. if test "${enable_dynamic_extensions+set}" = set; then : enableval=$enable_dynamic_extensions; if test "x$enableval" = "xno" ; then dynamic_extensions=no; else dynamic_extensions=yes; fi fi # check compiler: ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # check archiver: test -n "$AR" || AR=ar # Extract the first word of "$AR", so it can be a program name with args. set dummy $AR; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_prog_ar+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_prog_ar"; then ac_cv_prog_ac_prog_ar="$ac_prog_ar" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_prog_ar="$AR" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_prog_ar" && ac_cv_prog_ac_prog_ar="false" fi fi ac_prog_ar=$ac_cv_prog_ac_prog_ar if test -n "$ac_prog_ar"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_ar" >&5 $as_echo "$ac_prog_ar" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # check linker: test -n "$LD" || LD=ld # Extract the first word of "$LD", so it can be a program name with args. set dummy $LD; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_prog_ld+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_prog_ld"; then ac_cv_prog_ac_prog_ld="$ac_prog_ld" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_prog_ld="$LD" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_prog_ld" && ac_cv_prog_ac_prog_ld="false" fi fi ac_prog_ld=$ac_cv_prog_ac_prog_ld if test -n "$ac_prog_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_ld" >&5 $as_echo "$ac_prog_ld" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # check ranlib: test -n "$RANLIB" || RANLIB=ranlib # Extract the first word of "$RANLIB", so it can be a program name with args. set dummy $RANLIB; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_prog_ranlib+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_prog_ranlib"; then ac_cv_prog_ac_prog_ranlib="$ac_prog_ranlib" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_prog_ranlib="$RANLIB" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_prog_ranlib" && ac_cv_prog_ac_prog_ranlib="false" fi fi ac_prog_ranlib=$ac_cv_prog_ac_prog_ranlib if test -n "$ac_prog_ranlib"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_ranlib" >&5 $as_echo "$ac_prog_ranlib" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # check installer: # Extract the first word of "install", so it can be a program name with args. set dummy install; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_prog_install+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_prog_install"; then ac_cv_prog_ac_prog_install="$ac_prog_install" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_prog_install="install" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_prog_install" && ac_cv_prog_ac_prog_install="false" fi fi ac_prog_install=$ac_cv_prog_ac_prog_install if test -n "$ac_prog_install"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_install" >&5 $as_echo "$ac_prog_install" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Output of: cat `find . -name "*.[c]"` | grep "^#include <.*>$" | sort | uniq #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include # help2man utility: { $as_echo "$as_me:${as_lineno-$LINENO}: checking help2man" >&5 $as_echo_n "checking help2man... " >&6; } if help2man --version >/dev/null 2>&1 ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: help2man" >&5 $as_echo "help2man" >&6; } ac_cv_help2man="yes" HELP2MAN=help2man else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ac_cv_help2man="no" HELP2MAN=true fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long string extension" >&5 $as_echo_n "checking for long string extension... " >&6; } tmpdir=`mktemp -d /tmp/fitsh.XXXXXX` echo 'char * somestring = __extension__ "QQRIQ";' > $tmpdir/test.c if $CC -c $tmpdir/test.c -o $tmpdir/test.o >/dev/null 2>&1 ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ac_cv_gcc_extension="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ac_cv_gcc_extension="no" fi rm -f -r $tmpdir if test "x$ac_cv_gcc_extension" = "xno" ; then CFLAGS="${CFLAGS} -DHAVE_NO_CC_EXTENSION" fi # check used headers: ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in ctype.h do : ac_fn_c_check_header_mongrel "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default" if test "x$ac_cv_header_ctype_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CTYPE_H 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done for ac_header in fcntl.h do : ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" if test "x$ac_cv_header_fcntl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FCNTL_H 1 _ACEOF fi done for ac_header in fnmatch.h do : ac_fn_c_check_header_mongrel "$LINENO" "fnmatch.h" "ac_cv_header_fnmatch_h" "$ac_includes_default" if test "x$ac_cv_header_fnmatch_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FNMATCH_H 1 _ACEOF fi done for ac_header in math.h do : ac_fn_c_check_header_mongrel "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default" if test "x$ac_cv_header_math_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MATH_H 1 _ACEOF fi done for ac_header in time.h do : ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" if test "x$ac_cv_header_time_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TIME_H 1 _ACEOF fi done for ac_header in errno.h do : ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default" if test "x$ac_cv_header_errno_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ERRNO_H 1 _ACEOF fi done for ac_header in unistd.h do : ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNISTD_H 1 _ACEOF fi done for ac_header in signal.h do : ac_fn_c_check_header_mongrel "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default" if test "x$ac_cv_header_signal_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SIGNAL_H 1 _ACEOF fi done for ac_header in sys/time.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" if test "x$ac_cv_header_sys_time_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TIME_H 1 _ACEOF fi done for ac_header in sys/ioctl.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_IOCTL_H 1 _ACEOF fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TYPES_H 1 _ACEOF fi done for ac_header in sys/stat.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default" if test "x$ac_cv_header_sys_stat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_STAT_H 1 _ACEOF fi done for ac_header in sys/mman.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mman_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_MMAN_H 1 _ACEOF fi done # Some OS-dependent functions: { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fnmatch in -lc" >&5 $as_echo_n "checking for fnmatch in -lc... " >&6; } if ${ac_cv_lib_c_fnmatch+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fnmatch (); int main () { return fnmatch (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c_fnmatch=yes else ac_cv_lib_c_fnmatch=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_fnmatch" >&5 $as_echo "$ac_cv_lib_c_fnmatch" >&6; } if test "x$ac_cv_lib_c_fnmatch" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBC 1 _ACEOF LIBS="-lc $LIBS" fi # dynamic library management/handling: { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlsym in -ldl" >&5 $as_echo_n "checking for dlsym in -ldl... " >&6; } if ${ac_cv_lib_dl_dlsym+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlsym (); int main () { return dlsym (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlsym=yes else ac_cv_lib_dl_dlsym=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlsym" >&5 $as_echo "$ac_cv_lib_dl_dlsym" >&6; } if test "x$ac_cv_lib_dl_dlsym" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlclose in -ldl" >&5 $as_echo_n "checking for dlclose in -ldl... " >&6; } if ${ac_cv_lib_dl_dlclose+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlclose (); int main () { return dlclose (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlclose=yes else ac_cv_lib_dl_dlclose=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlclose" >&5 $as_echo "$ac_cv_lib_dl_dlclose" >&6; } if test "x$ac_cv_lib_dl_dlclose" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi ax_cflags_gcc_no_overlength_strings=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for gcc -Wno-overlength-strings" >&5 $as_echo_n "checking CFLAGS for gcc -Wno-overlength-strings... " >&6; } if ${ac_cv_cflags_gcc_option__Wno_overlength_strings+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_cflags_gcc_option__Wno_overlength_strings="no, unknown" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_save_CFLAGS="$CFLAGS" for ac_arg in "-pedantic -Werror % -Wno-overlength-strings" "-pedantic % -Wno-overlength-strings %% no, obsolete" # do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_cflags_gcc_option__Wno_overlength_strings=`echo $ac_arg | sed -e 's,.*% *,,'` ; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CFLAGS="$ac_save_CFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_gcc_option__Wno_overlength_strings" >&5 $as_echo "$ac_cv_cflags_gcc_option__Wno_overlength_strings" >&6; } case ".$ac_cv_cflags_gcc_option__Wno_overlength_strings" in .ok|.ok,*) ax_cflags_gcc_no_overlength_strings=yes ;; .|.no|.no,*) ;; *) ax_cflags_gcc_no_overlength_strings=yes ;; esac if test $cflags_default == yes && test $ax_cflags_gcc_no_overlength_strings == yes ; then CFLAGS="$CFLAGS -Wno-overlength-strings" fi ax_cflags_gcc_no_long_long=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for gcc -Wno-long-long" >&5 $as_echo_n "checking CFLAGS for gcc -Wno-long-long... " >&6; } if ${ac_cv_cflags_gcc_option__Wno_long_long+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_cflags_gcc_option__Wno_long_long="no, unknown" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_save_CFLAGS="$CFLAGS" for ac_arg in "-pedantic -Werror % -Wno-long-long" "-pedantic % -Wno-long-long %% no, obsolete" # do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_cflags_gcc_option__Wno_long_long=`echo $ac_arg | sed -e 's,.*% *,,'` ; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CFLAGS="$ac_save_CFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_gcc_option__Wno_long_long" >&5 $as_echo "$ac_cv_cflags_gcc_option__Wno_long_long" >&6; } case ".$ac_cv_cflags_gcc_option__Wno_long_long" in .ok|.ok,*) ax_cflags_gcc_no_long_long=yes ;; .|.no|.no,*) ;; *) ax_cflags_gcc_no_long_long=yes ;; esac if test $cflags_default == yes && test $ax_cflags_gcc_no_long_long == yes ; then CFLAGS="$CFLAGS -Wno-long-long" fi ax_cflags_gcc_no_unused_result=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for gcc -Wno-unused-result" >&5 $as_echo_n "checking CFLAGS for gcc -Wno-unused-result... " >&6; } if ${ac_cv_cflags_gcc_option__Wno_unused_result+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_cflags_gcc_option__Wno_unused_result="no, unknown" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_save_CFLAGS="$CFLAGS" for ac_arg in "-pedantic -Werror % -Wno-unused-result" "-pedantic % -Wno-unused-result %% no, obsolete" # do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_cflags_gcc_option__Wno_unused_result=`echo $ac_arg | sed -e 's,.*% *,,'` ; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done CFLAGS="$ac_save_CFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_gcc_option__Wno_unused_result" >&5 $as_echo "$ac_cv_cflags_gcc_option__Wno_unused_result" >&6; } case ".$ac_cv_cflags_gcc_option__Wno_unused_result" in .ok|.ok,*) ax_cflags_gcc_no_unused_result=yes ;; .|.no|.no,*) ;; *) ax_cflags_gcc_no_unused_result=yes ;; esac if test $cflags_default == yes && test $ax_cflags_gcc_no_unused_result == yes ; then CFLAGS="$CFLAGS -Wno-unused-result" fi if test "x$ac_cv_header_fnmatch_h" != "xyes" || \ test "x$ac_cv_lib_c_fnmatch" != "xyes" ; then CFLAGS="${CFLAGS} -DHAVE_NO_FNMATCH_H" fi # some additional functions: # basic math functions: { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5 $as_echo_n "checking for sin in -lm... " >&6; } if ${ac_cv_lib_m_sin+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sin (); int main () { return sin (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_sin=yes else ac_cv_lib_m_sin=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5 $as_echo "$ac_cv_lib_m_sin" >&6; } if test "x$ac_cv_lib_m_sin" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cos (); int main () { return cos (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_cos=yes else ac_cv_lib_m_cos=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } if test "x$ac_cv_lib_m_cos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tan in -lm" >&5 $as_echo_n "checking for tan in -lm... " >&6; } if ${ac_cv_lib_m_tan+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tan (); int main () { return tan (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_tan=yes else ac_cv_lib_m_tan=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_tan" >&5 $as_echo "$ac_cv_lib_m_tan" >&6; } if test "x$ac_cv_lib_m_tan" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for asin in -lm" >&5 $as_echo_n "checking for asin in -lm... " >&6; } if ${ac_cv_lib_m_asin+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char asin (); int main () { return asin (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_asin=yes else ac_cv_lib_m_asin=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_asin" >&5 $as_echo "$ac_cv_lib_m_asin" >&6; } if test "x$ac_cv_lib_m_asin" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acos in -lm" >&5 $as_echo_n "checking for acos in -lm... " >&6; } if ${ac_cv_lib_m_acos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acos (); int main () { return acos (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_acos=yes else ac_cv_lib_m_acos=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_acos" >&5 $as_echo "$ac_cv_lib_m_acos" >&6; } if test "x$ac_cv_lib_m_acos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan in -lm" >&5 $as_echo_n "checking for atan in -lm... " >&6; } if ${ac_cv_lib_m_atan+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char atan (); int main () { return atan (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_atan=yes else ac_cv_lib_m_atan=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atan" >&5 $as_echo "$ac_cv_lib_m_atan" >&6; } if test "x$ac_cv_lib_m_atan" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan2 in -lm" >&5 $as_echo_n "checking for atan2 in -lm... " >&6; } if ${ac_cv_lib_m_atan2+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char atan2 (); int main () { return atan2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_atan2=yes else ac_cv_lib_m_atan2=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atan2" >&5 $as_echo "$ac_cv_lib_m_atan2" >&6; } if test "x$ac_cv_lib_m_atan2" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 $as_echo_n "checking for sqrt in -lm... " >&6; } if ${ac_cv_lib_m_sqrt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sqrt (); int main () { return sqrt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_sqrt=yes else ac_cv_lib_m_sqrt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 $as_echo "$ac_cv_lib_m_sqrt" >&6; } if test "x$ac_cv_lib_m_sqrt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for log in -lm" >&5 $as_echo_n "checking for log in -lm... " >&6; } if ${ac_cv_lib_m_log+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char log (); int main () { return log (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_log=yes else ac_cv_lib_m_log=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_log" >&5 $as_echo "$ac_cv_lib_m_log" >&6; } if test "x$ac_cv_lib_m_log" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exp in -lm" >&5 $as_echo_n "checking for exp in -lm... " >&6; } if ${ac_cv_lib_m_exp+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char exp (); int main () { return exp (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_exp=yes else ac_cv_lib_m_exp=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_exp" >&5 $as_echo "$ac_cv_lib_m_exp" >&6; } if test "x$ac_cv_lib_m_exp" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for log10 in -lm" >&5 $as_echo_n "checking for log10 in -lm... " >&6; } if ${ac_cv_lib_m_log10+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char log10 (); int main () { return log10 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_log10=yes else ac_cv_lib_m_log10=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_log10" >&5 $as_echo "$ac_cv_lib_m_log10" >&6; } if test "x$ac_cv_lib_m_log10" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exp10 in -lm" >&5 $as_echo_n "checking for exp10 in -lm... " >&6; } if ${ac_cv_lib_m_exp10+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char exp10 (); int main () { return exp10 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_exp10=yes else ac_cv_lib_m_exp10=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_exp10" >&5 $as_echo "$ac_cv_lib_m_exp10" >&6; } if test "x$ac_cv_lib_m_exp10" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 $as_echo_n "checking for pow in -lm... " >&6; } if ${ac_cv_lib_m_pow+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pow (); int main () { return pow (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_pow=yes else ac_cv_lib_m_pow=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 $as_echo "$ac_cv_lib_m_pow" >&6; } if test "x$ac_cv_lib_m_pow" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5 $as_echo_n "checking for floor in -lm... " >&6; } if ${ac_cv_lib_m_floor+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char floor (); int main () { return floor (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_floor=yes else ac_cv_lib_m_floor=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5 $as_echo "$ac_cv_lib_m_floor" >&6; } if test "x$ac_cv_lib_m_floor" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fmod in -lm" >&5 $as_echo_n "checking for fmod in -lm... " >&6; } if ${ac_cv_lib_m_fmod+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fmod (); int main () { return fmod (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_fmod=yes else ac_cv_lib_m_fmod=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fmod" >&5 $as_echo "$ac_cv_lib_m_fmod" >&6; } if test "x$ac_cv_lib_m_fmod" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for finite in -lm" >&5 $as_echo_n "checking for finite in -lm... " >&6; } if ${ac_cv_lib_m_finite+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char finite (); int main () { return finite (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_finite=yes else ac_cv_lib_m_finite=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_finite" >&5 $as_echo "$ac_cv_lib_m_finite" >&6; } if test "x$ac_cv_lib_m_finite" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isnan in -lm" >&5 $as_echo_n "checking for isnan in -lm... " >&6; } if ${ac_cv_lib_m_isnan+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char isnan (); int main () { return isnan (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_isnan=yes else ac_cv_lib_m_isnan=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_isnan" >&5 $as_echo "$ac_cv_lib_m_isnan" >&6; } if test "x$ac_cv_lib_m_isnan" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isinf in -lm" >&5 $as_echo_n "checking for isinf in -lm... " >&6; } if ${ac_cv_lib_m_isinf+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char isinf (); int main () { return isinf (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_isinf=yes else ac_cv_lib_m_isinf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_isinf" >&5 $as_echo "$ac_cv_lib_m_isinf" >&6; } if test "x$ac_cv_lib_m_isinf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi # Debian archiver: { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a debian archiver" >&5 $as_echo_n "checking for a debian archiver... " >&6; } if dpkg-deb --version >/dev/null 2>&1 ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: dpkg-deb" >&5 $as_echo "dpkg-deb" >&6; } ac_cv_debian_archiver="yes" DPKG_DEB=dpkg-deb else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ac_cv_debian_archiver="no" DPKG_DEB=false fi # Groff: { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a roff formatter" >&5 $as_echo_n "checking for a roff formatter... " >&6; } if groff --version >/dev/null 2>&1 ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: groff" >&5 $as_echo "groff" >&6; } ac_cv_roff_groff="yes" ROFF=groff else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ac_cv_roff_groff="no" ROFF=false fi # Extract the first word of "man", so it can be a program name with args. set dummy man; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_prog_man+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_prog_man"; then ac_cv_prog_ac_prog_man="$ac_prog_man" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_prog_man="man" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_prog_man" && ac_cv_prog_ac_prog_man="false" fi fi ac_prog_man=$ac_cv_prog_ac_prog_man if test -n "$ac_prog_man"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_man" >&5 $as_echo "$ac_prog_man" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "dvips", so it can be a program name with args. set dummy dvips; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_prog_dvips+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_prog_dvips"; then ac_cv_prog_ac_prog_dvips="$ac_prog_dvips" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_prog_dvips="dvips" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_prog_dvips" && ac_cv_prog_ac_prog_dvips="false" fi fi ac_prog_dvips=$ac_cv_prog_ac_prog_dvips if test -n "$ac_prog_dvips"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_dvips" >&5 $as_echo "$ac_prog_dvips" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gzip", so it can be a program name with args. set dummy gzip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_prog_gzip+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_prog_gzip"; then ac_cv_prog_ac_prog_gzip="$ac_prog_gzip" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_prog_gzip="gzip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_prog_gzip" && ac_cv_prog_ac_prog_gzip="false" fi fi ac_prog_gzip=$ac_cv_prog_ac_prog_gzip if test -n "$ac_prog_gzip"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_gzip" >&5 $as_echo "$ac_prog_gzip" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Check paper size: { $as_echo "$as_me:${as_lineno-$LINENO}: checking papersize" >&5 $as_echo_n "checking papersize... " >&6; } if test -x /usr/bin/paperconf ; then PAPERSIZE=`/usr/bin/paperconf` PAPER_WIDTH=`/usr/bin/paperconf -w` PAPER_HEIGHT=`/usr/bin/paperconf -h` elif test -f /etc/papersize ; then PAPERSIZE=`grep -v "^\#" /etc/papersize | head -1` PAPER_WIDTH=0 PAPER_HEIGHT=0 else PAPERSIZE=letter PAPER_WIDTH=612 PAPER_HEIGHT=792 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PAPERSIZE: ${PAPER_WIDTH}x${PAPER_HEIGHT}" >&5 $as_echo "$PAPERSIZE: ${PAPER_WIDTH}x${PAPER_HEIGHT}" >&6; } ARCH=`uname -m` { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic library extensions (HOST=$HOST)" >&5 $as_echo_n "checking dynamic library extensions (HOST=$HOST)... " >&6; } if test `uname` == Darwin; then OSX_VERSION=`sw_vers -productVersion` DLEXT=dylib DLSWC="-dylib -arch $ARCH -macosx_version_min $OSX_VERSION" DLDYN=-dynamic DLLIB=-ldl { $as_echo "$as_me:${as_lineno-$LINENO}: result: dylib" >&5 $as_echo "dylib" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: OSX linker flags: $DLSWC" >&5 $as_echo "$as_me: OSX linker flags: $DLSWC" >&6;} elif test "$HOST" == win32; then DLEXT= DLSWC= DLDYN= DLLIB= { $as_echo "$as_me:${as_lineno-$LINENO}: result: not supported" >&5 $as_echo "not supported" >&6; } elif test "$HOST" == win64; then DLEXT= DLSWC= DLDYN= DLLIB= { $as_echo "$as_me:${as_lineno-$LINENO}: result: not supported" >&5 $as_echo "not supported" >&6; } elif test `uname` == NetBSD; then DLEXT=so DLSWC=-shared DLDYN=-rdynamic DLLIB= { $as_echo "$as_me:${as_lineno-$LINENO}: result: so" >&5 $as_echo "so" >&6; } else DLEXT=so DLSWC=-shared DLDYN=-rdynamic DLLIB=-ldl { $as_echo "$as_me:${as_lineno-$LINENO}: result: so" >&5 $as_echo "so" >&6; } fi DEB_ARCH=`uname -m | sed -e 's/x86_64/amd64/' -e 's/i486/i386/' -e 's/i586/i386/' -e 's/i686/i386/'` DEB_VERSION=$PACKAGE_VERSION FITSH_VERSION=$PACKAGE_VERSION FITSH_RELEASE=$RELEASE_DATE # Final notices: { $as_echo "$as_me:${as_lineno-$LINENO}: generic: using CFLAGS: ${CFLAGS}" >&5 $as_echo "$as_me: generic: using CFLAGS: ${CFLAGS}" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: generic: using Debian architecture identifier: ${DEB_ARCH}" >&5 $as_echo "$as_me: generic: using Debian architecture identifier: ${DEB_ARCH}" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: \`lfit\`: may use dynamic extensions: $dynamic_extensions" >&5 $as_echo "$as_me: \`lfit\`: may use dynamic extensions: $dynamic_extensions" >&6;} # Substitution for binary object archiver and linker: AR=${ac_prog_ar} LD=${ac_prog_ld} RANLIB=${ac_prog_ranlib} INSTALL=${ac_prog_install} # Substitution for dynamic loading and additional optional supported methods: DLEXT=${DLEXT} DLSWC=${DLSWC} DLDYN=${DLDYN} DLLIB=${DLLIB} # Substitution for documentation and distribution management: DEB_VERSION=${DEB_VERSION} DEB_ARCH=${DEB_ARCH} DPKG_DEB=${DPKG_DEB} HELP2MAN=${HELP2MAN} ROFF=${ROFF} GZIP=${ac_prog_gzip} MAN=${ac_prog_man} DVIPS=${ac_prog_dvips} PAPERSIZE=${PAPERSIZE} PAPER_WIDTH=${PAPER_WIDTH} PAPER_HEIGHT=${PAPER_HEIGHT} # Substitution for the config.h header: FITSH_VERSION=${FITSH_VERSION} FITSH_RELEASE=${FITSH_RELEASE} ac_output_list="Makefile config.h libastro/Makefile libfits/Makefile librandom/Makefile libpsn/Makefile src/Makefile src/index/Makefile src/io/Makefile src/link/Makefile src/math/Makefile src/math/dft/Makefile src/math/elliptic/Makefile src/math/elliptic/Makefile src/math/expint/Makefile src/math/fit/Makefile src/math/intersec/Makefile src/math/spline/Makefile src/psn/Makefile doc/Makefile doc/examples/Makefile doc/examples/firandom/Makefile" ac_config_files="$ac_config_files ${ac_output_list}" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by fitsh $as_me 0.9.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ fitsh config.status 0.9.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "${ac_output_list}") CONFIG_FILES="$CONFIG_FILES ${ac_output_list}" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi