Imported healpix tree

This commit is contained in:
Guilhem Lavaux 2012-10-30 13:56:48 -04:00
parent 4182c30485
commit 4bfb62f177
136 changed files with 26534 additions and 0 deletions

340
external/healpix/COPYING vendored Normal file
View file

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) 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
this service 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE 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.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -0,0 +1,133 @@
/*! \mainpage HEALPix C++ documentation
<ul>
<li>\ref components "Programming interface"
<li>\ref facilities "Facilities"
</ul>
*/
/*! \page components Code components
Classes:
- Healpix_Base contains all functionality related to the HEALPix
pixelisation which does not require actual map data.
- Healpix_Base2 is analogous to Healpix_Base, but allows for much
higher resolutions.
- Healpix_Map is derived from Healpix_Base and implements
additional functionality like change of the ordering scheme, up- and
degrading and interpolation.
- Alm is used to store spherical harmonic coefficients.
- PowSpec is used to store \f$C_l\f$ coefficients.
Conversions between different data types:
- \ref alm_healpix_group "HEALPix maps <-> a_lm".
- \ref alm_ps_group "power spectra <-> a_lm".
FITS I/O:
- for \ref healpix_map_fitsio_group "HEALPix Maps"
- for \ref alm_fitsio_group "spherical harmonic coefficients"
- for \ref powspec_fitsio_group "power spectra"
*/
/*! \page facilities HEALPix C++ facilities
\section syn_alm_cxx
This program reads a set of \f$C_l\f$ from disk and converts it to
a set of \f$a_{lm}\f$.
\verbinclude syn_alm_cxx.par.txt
\section alm2map_cxx
This program reads a set of \f$a_{lm}\f$ from disk and converts them to
a HEALPix map.
\verbinclude alm2map_cxx.par.txt
\section anafast_cxx
This program performs harmonic analysis of a HEALPix map up to a
user-specified maximum spherical harmonic order \f$l_{\mbox{max}}\f$.
The integrals are computed on the whole sphere.
Scalar, or scalar and tensor, spherical harmonic coefficients are evaluated
from the map(s) if the input provides, respectively, only the temperature,
or temperature and polarisation maps.
The total operation count scales as \f${\cal {O}}(N_{\mbox{pix}}^{3/2})\f$
with a prefactor depending on \f$l_{\mbox{max}}\f$.
Anafast_cxx reads a file containing the map(s) and produces a file
containing the temperature power spectrum \f$C^T_l\f$ and, if requested,
also the polarisation power spectra \f$C^E_l\f$, \f$C^B_l\f$ and
\f$C^{T\times E}_l\f$. The \f$a_{lm}\f$ coefficients computed during the
execution also can be written to a file if requested.
Anafast_cxx executes an approximate, discrete point-set quadrature on
a sphere sampled at the HEALPix pixel centers.
Spherical harmonic transforms are computed using recurrence relations for
Legendre polynomials on co-latitude (\f$\vartheta\f$) and Fast Fourier
transforms on longitude (\f$\varphi\f$).
Anafast permits two execution options which allow a significant
improvement of accuracy of the approximate quadrature performed by
this facility:
- An improved analysis using the provided ring weights, which correct the
quadrature on latitude, and/or
- An iterative scheme using in succession several backward and forward
harmonic transforms of the maps.
\verbinclude anafast_cxx.par.txt
\section map2tga
This program reads in a HEALPix sky map in FITS format and generates an
image in TGA format. map2tga allows the selection of the projection
scheme (Mollweide or Gnomonic for small patches of the sky), color
table, color bar inclusion, linear or log scaling, maximum and
minimum range for the plot and plot-title. The facility provides
a command-line interface, but can also read a parameter file.
\verbinclude map2tga.par.txt
\section rotalm_cxx
Performs a coordinate transformation on a set of \f$a_{lm}\f$.
\verbatim
Usage: rotalm_cxx <infile> <outfile> <itransform> <pol>
Transform 1: Equatorial (2000) -> Galactic (2000)
2: Galactic (2000) -> Equatorial (2000)
3: Equatorial (2000) -> Ecliptic (2000)
4: Ecliptic (2000) -> Equatorial (2000)
5: Ecliptic (2000) -> Galactic (2000)
6: Galactic (2000) -> Ecliptic (2000)
7: Equatorial (1950) -> Galactic (1950)
8: Galactic (1950) -> Equatorial (1950)
9: Equatorial (1950) -> Ecliptic (1950)
10: Ecliptic (1950) -> Equatorial (1950)
11: Ecliptic (1950) -> Galactic (1950)
12: Galactic (1950) -> Ecliptic (1950)
\endverbatim
\section mult_alm
This program reads a set of (unpolarised or polarised) \f$a_{lm}\f$,
removes pixel window functions and/or Gaussian beams, applies different
pixel window functions or Gaussian beams, and outputs the result.
\verbinclude mult_alm.par.txt
\section smoothing_cxx
This program reads a (unpolarised or polarised) HEALPix map, converts it
to \f$a_{lm}\f$, performs a smoothing operation with a Gaussian beam,
converts the \f$a_{lm}\f$ back to a map and outputs the result.
\verbinclude smoothing_cxx.par.txt
\section calc_powspec
This program reads one or two sets of \f$a_{lm}\f$, extracts the
(unpolarised or polarised) power spectrum or the unpolarised cross power
spectrum, and outputs the result.
\verbatim Usage: calc_powspec <almfile1> [<almfile2>] <powspec_file>\endverbatim
\section median_filter_cxx
This program inputs a HEALPix map, runs a median filter with the desired
radius on it and saves the result to another file.
\verbatim Usage: median_filter_cxx <input map> <output map> <radius in arcmin>\endverbatim
*/

177
external/healpix/Healpix_cxx/alm.h vendored Normal file
View file

@ -0,0 +1,177 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file alm.h
* Class for storing spherical harmonic coefficients.
*
* Copyright (C) 2003 - 2009 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_ALM_H
#define PLANCK_ALM_H
#include "arr.h"
/*! Base class for calculating the storage layout of spherical harmonic
coefficients. */
class Alm_Base
{
protected:
int lmax, mmax, tval;
public:
/*! Returns the total number of coefficients for maximum quantum numbers
\a l and \a m. */
static tsize Num_Alms (int l, int m)
{
planck_assert(m<=l,"mmax must not be larger than lmax");
return ((m+1)*(m+2))/2 + (m+1)*(l-m);
}
/*! Constructs an Alm_Base object with given \a lmax and \a mmax. */
Alm_Base (int lmax_=0, int mmax_=0)
: lmax(lmax_), mmax(mmax_), tval(2*lmax+1) {}
/*! Changes the object's maximum quantum numbers to \a lmax and \a mmax. */
void Set (int lmax_, int mmax_)
{
lmax=lmax_;
mmax=mmax_;
tval=2*lmax+1;
}
/*! Returns the maximum \a l */
int Lmax() const { return lmax; }
/*! Returns the maximum \a m */
int Mmax() const { return mmax; }
/*! Returns an array index for a given m, from which the index of a_lm
can be obtained by adding l. */
int index_l0 (int m) const
{ return ((m*(tval-m))>>1); }
/*! Returns the array index of the specified coefficient. */
int index (int l, int m) const
{ return index_l0(m) + l; }
/*! Returns \a true, if both objects have the same \a lmax and \a mmax,
else \a false. */
bool conformable (const Alm_Base &other) const
{ return ((lmax==other.lmax) && (mmax==other.mmax)); }
/*! Swaps the contents of two Alm_Base objects. */
void swap (Alm_Base &other)
{
std::swap(lmax, other.lmax);
std::swap(mmax, other.mmax);
std::swap(tval, other.tval);
}
};
/*! Class for storing spherical harmonic coefficients. */
template<typename T> class Alm: public Alm_Base
{
private:
arr<T> alm;
public:
/*! Constructs an Alm object with given \a lmax and \a mmax. */
Alm (int lmax_=0, int mmax_=0)
: Alm_Base(lmax_,mmax_), alm (Num_Alms(lmax,mmax)) {}
/*! Deletes the old coefficients and allocates storage according to
\a lmax and \a mmax. */
void Set (int lmax_, int mmax_)
{
Alm_Base::Set(lmax_, mmax_);
alm.alloc(Num_Alms(lmax,mmax));
}
/*! Deallocates the old coefficients and uses the content of \a data
for storage. \a data is deallocated during the call. */
void Set (arr<T> &data, int lmax_, int mmax_)
{
planck_assert (Num_Alms(lmax_,mmax_)==data.size(),"wrong array size");
Alm_Base::Set(lmax_, mmax_);
alm.transfer(data);
}
/*! Sets all coefficients to zero. */
void SetToZero ()
{ alm.fill (0); }
/*! Multiplies all coefficients by \a factor. */
template<typename T2> void Scale (const T2 &factor)
{ for (tsize m=0; m<alm.size(); ++m) alm[m]*=factor; }
/*! \a a(l,m) *= \a factor[l] for all \a l,m. */
template<typename T2> void ScaleL (const arr<T2> &factor)
{
planck_assert(factor.size()>tsize(lmax),
"alm.ScaleL: factor array too short");
for (int m=0; m<=mmax; ++m)
for (int l=m; l<=lmax; ++l)
operator()(l,m)*=factor[l];
}
/*! Adds \a num to a_00. */
template<typename T2> void Add (const T2 &num)
{ alm[0]+=num; }
/*! Returns a reference to the specified coefficient. */
T &operator() (int l, int m)
{ return alm[index(l,m)]; }
/*! Returns a constant reference to the specified coefficient. */
const T &operator() (int l, int m) const
{ return alm[index(l,m)]; }
/*! Returns a pointer for a given m, from which the address of a_lm
can be obtained by adding l. */
T *mstart (int m)
{ return &alm[index_l0(m)]; }
/*! Returns a pointer for a given m, from which the address of a_lm
can be obtained by adding l. */
const T *mstart (int m) const
{ return &alm[index_l0(m)]; }
/*! Returns a constant reference to the a_lm data. */
const arr<T> &Alms () const { return alm; }
/*! Swaps the contents of two Alm objects. */
void swap (Alm &other)
{
Alm_Base::swap(other);
alm.swap(other.alm);
}
/*! Adds all coefficients from \a other to the own coefficients. */
void Add (const Alm &other)
{
planck_assert (conformable(other), "A_lm are not conformable");
for (tsize m=0; m<alm.size(); ++m)
alm[m] += other.alm[m];
}
};
#endif

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
alm2map_cxx_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,36 @@
Parameters read by alm2map_cxx:
nlmax (integer):
maximum order of l
nmmax (integer):
maximum order of m (must not be larger than nlmax, default=nlmax)
infile (string):
input file containing the a_lm
outfile (string):
output file name for the Healpix map(s)
nside (integer):
nside parameter for the output map(s)
polarisation (bool):
if false, only the intensity map is generated,
if true, maps for I, Q and U are generated
fwhm_arcmin (double, default=0):
FWHM in arc minutes of a Gaussian beam, which is used to smooth
the a_lm
pixel_window (bool, default=false):
if true, the a_lm are multiplied by the appropriate pixel window function
if (pixel_window)
healpix_data (string):
directory containing the Healpix data files
endif
double_precision (bool, default=false):
if false, a_lm and maps are read/written in single precision,
otherwise in double precision.

View file

@ -0,0 +1,125 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "xcomplex.h"
#include "cxxutils.h"
#include "paramfile.h"
#include "healpix_data_io.h"
#include "alm.h"
#include "alm_fitsio.h"
#include "healpix_map.h"
#include "healpix_map_fitsio.h"
#include "alm_healpix_tools.h"
#include "alm_powspec_tools.h"
#include "fitshandle.h"
#include "levels_facilities.h"
#include "lsconstants.h"
using namespace std;
namespace {
template<typename T> void alm2map_cxx (paramfile &params)
{
int nlmax = params.template find<int>("nlmax");
int nmmax = params.template find<int>("nmmax",nlmax);
planck_assert(nmmax<=nlmax,"nmmax must not be larger than nlmax");
string infile = params.template find<string>("infile");
string outfile = params.template find<string>("outfile");
int nside = params.template find<int>("nside");
double fwhm = arcmin2rad*params.template find<double>("fwhm_arcmin",0);
arr<double> temp, pol;
get_pixwin (params,nlmax,nside,temp,pol);
bool deriv = params.template find<bool>("derivatives",false);
if (deriv)
{
Alm<xcomplex<T> > alm;
read_Alm_from_fits(infile,alm,nlmax,nmmax,2);
if (fwhm>0) smoothWithGauss (alm, fwhm);
Healpix_Map<T> map(nside,RING,SET_NSIDE),
mapdth(nside,RING,SET_NSIDE),
mapdph(nside,RING,SET_NSIDE);
alm.ScaleL(temp);
double offset = alm(0,0).real()/sqrt(fourpi);
alm(0,0) = 0;
alm2map_der1(alm,map,mapdth,mapdph);
map.Add(T(offset));
write_Healpix_map_to_fits (outfile,map,mapdth,mapdph,planckType<T>());
return;
}
bool polarisation = params.template find<bool>("polarisation");
if (!polarisation)
{
Alm<xcomplex<T> > alm;
read_Alm_from_fits(infile,alm,nlmax,nmmax,2);
if (fwhm>0) smoothWithGauss (alm, fwhm);
Healpix_Map<T> map(nside,RING,SET_NSIDE);
alm.ScaleL(temp);
double offset = alm(0,0).real()/sqrt(fourpi);
alm(0,0) = 0;
alm2map(alm,map);
map.Add(T(offset));
write_Healpix_map_to_fits (outfile,map,planckType<T>());
}
else
{
Alm<xcomplex<T> > almT, almG, almC;
read_Alm_from_fits(infile,almT,almG,almC,nlmax,nmmax,2);
if (fwhm>0) smoothWithGauss (almT, almG, almC, fwhm);
Healpix_Map<T> mapT(nside,RING,SET_NSIDE), mapQ(nside,RING,SET_NSIDE),
mapU(nside,RING,SET_NSIDE);
almT.ScaleL(temp);
almG.ScaleL(pol); almC.ScaleL(pol);
double offset = almT(0,0).real()/sqrt(fourpi);
almT(0,0) = 0;
alm2map_pol(almT,almG,almC,mapT,mapQ,mapU);
mapT.Add(T(offset));
write_Healpix_map_to_fits (outfile,mapT,mapQ,mapU,planckType<T>());
}
}
} // unnamed namespace
int alm2map_cxx_module (int argc, const char **argv)
{
module_startup ("alm2map_cxx", argc, argv, 2, "<parameter file>");
paramfile params (argv[1]);
bool dp = params.find<bool> ("double_precision",false);
dp ? alm2map_cxx<double>(params) : alm2map_cxx<float>(params);
return 0;
}

View file

@ -0,0 +1,250 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include <string>
#include "alm_fitsio.h"
#include "alm.h"
#include "fitshandle.h"
#include "xcomplex.h"
#include "safe_cast.h"
using namespace std;
void get_almsize(fitshandle &inp, int &lmax, int &mmax)
{
if (inp.key_present("MAX-LPOL") && inp.key_present("MAX-MPOL"))
{
inp.get_key ("MAX-LPOL",lmax);
inp.get_key ("MAX-MPOL",mmax);
return;
}
int n_alms = safe_cast<int>(inp.nelems(1));
arr<int> index;
lmax=mmax=-1;
chunkMaker cm(n_alms,inp.efficientChunkSize(1));
uint64 offset,ppix;
while(cm.getNext(offset,ppix))
{
index.alloc(ppix);
inp.read_column(1,index,offset);
for (tsize i=0; i<ppix; ++i)
{
int l = isqrt(index[i]-1);
int m = index[i] - l*l - l - 1;
if (l>lmax) lmax=l;
if (m>mmax) mmax=m;
}
}
}
void get_almsize(const string &filename, int &lmax, int &mmax, int hdunum)
{
fitshandle inp;
inp.open (filename);
inp.goto_hdu(hdunum);
get_almsize (inp, lmax, mmax);
}
void get_almsize_pol(const string &filename, int &lmax, int &mmax)
{
int tlmax, tmmax;
fitshandle inp;
inp.open (filename);
lmax=mmax=0;
for (int hdu=2; hdu<=4; ++hdu)
{
inp.goto_hdu(hdu);
get_almsize (inp,tlmax,tmmax);
if (tlmax>lmax) lmax=tlmax;
if (tmmax>mmax) mmax=tmmax;
}
}
template<typename T> void read_Alm_from_fits
(fitshandle &inp, Alm<xcomplex<T> >&alms, int lmax, int mmax)
{
int n_alms = safe_cast<int>(inp.nelems(1));
arr<int> index;
arr<T> re, im;
alms.Set(lmax, mmax);
alms.SetToZero();
int max_index = lmax*lmax + lmax + mmax + 1;
chunkMaker cm(n_alms,inp.efficientChunkSize(1));
uint64 offset,ppix;
while(cm.getNext(offset,ppix))
{
index.alloc(ppix);
re.alloc(ppix); im.alloc(ppix);
inp.read_column(1,index,offset);
inp.read_column(2,re,offset);
inp.read_column(3,im,offset);
for (tsize i=0; i<ppix; ++i)
{
if (index[i]>max_index) return;
int l = isqrt(index[i]-1);
int m = index[i] - l*l - l - 1;
planck_assert(m>=0,"negative m encountered");
planck_assert(l>=m, "wrong l,m combination");
if ((l<=lmax) && (m<=mmax))
alms(l,m).Set (re[i], im[i]);
}
}
}
template void read_Alm_from_fits (fitshandle &inp,
Alm<xcomplex<double> > &alms, int lmax, int mmax);
template void read_Alm_from_fits (fitshandle &inp,
Alm<xcomplex<float> > &alms, int lmax, int mmax);
template<typename T> void read_Alm_from_fits
(const string &filename, Alm<xcomplex<T> >&alms, int lmax, int mmax,
int hdunum)
{
fitshandle inp;
inp.open (filename);
inp.goto_hdu(hdunum);
read_Alm_from_fits(inp,alms,lmax,mmax);
}
template void read_Alm_from_fits (const string &filename,
Alm<xcomplex<double> > &alms, int lmax, int mmax, int hdunum);
template void read_Alm_from_fits (const string &filename,
Alm<xcomplex<float> > &alms, int lmax, int mmax, int hdunum);
template<typename T> void write_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<T> > &alms, int lmax, int mmax,
PDT datatype)
{
vector<fitscolumn> cols;
cols.push_back (fitscolumn("index","l*l+l+m+1",1,PLANCK_INT32));
cols.push_back (fitscolumn("real","unknown",1,datatype));
cols.push_back (fitscolumn("imag","unknown",1,datatype));
out.insert_bintab(cols);
arr<int> index;
arr<double> re, im;
int lm=alms.Lmax(), mm=alms.Mmax();
int n_alms = ((mmax+1)*(mmax+2))/2 + (mmax+1)*(lmax-mmax);
int l=0, m=0;
chunkMaker cm(n_alms,out.efficientChunkSize(1));
uint64 offset,ppix;
while(cm.getNext(offset,ppix))
{
index.alloc(ppix);
re.alloc(ppix); im.alloc(ppix);
for (tsize i=0; i<ppix; ++i)
{
index[i] = l*l + l + m + 1;
if ((l<=lm) && (m<=mm))
{ re[i] = alms(l,m).re; im[i] = alms(l,m).im; }
else
{ re[i] = 0; im[i] = 0; }
++m;
if ((m>l) || (m>mmax)) { ++l; m=0; }
}
out.write_column(1,index,offset);
out.write_column(2,re,offset);
out.write_column(3,im,offset);
}
out.set_key("MAX-LPOL",lmax,"highest l in the table");
out.set_key("MAX-MPOL",mmax,"highest m in the table");
}
template void write_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<double> > &alms, int lmax,
int mmax, PDT datatype);
template void write_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<float> > &alms, int lmax,
int mmax, PDT datatype);
template<typename T> void write_compressed_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<T> > &alms, int lmax, int mmax,
PDT datatype)
{
vector<fitscolumn> cols;
cols.push_back (fitscolumn("index","l*l+l+m+1",1,PLANCK_INT32));
cols.push_back (fitscolumn("real","unknown",1,datatype));
cols.push_back (fitscolumn("imag","unknown",1,datatype));
out.insert_bintab(cols);
arr<int> index;
arr<double> re, im;
int n_alms = 0;
for (int m=0; m<=mmax; ++m)
for (int l=m; l<=lmax; ++l)
if (alms(l,m).norm()>0) ++n_alms;
int l=0, m=0;
int real_lmax=0, real_mmax=0;
chunkMaker cm(n_alms,out.efficientChunkSize(1));
uint64 offset,ppix;
while(cm.getNext(offset,ppix))
{
index.alloc(ppix);
re.alloc(ppix); im.alloc(ppix);
for (tsize i=0; i<ppix; ++i)
{
while (alms(l,m).norm()==0)
{
++m;
if ((m>l) || (m>mmax)) { ++l; m=0; }
}
index[i] = l*l + l + m + 1;
re[i] = alms(l,m).re;
im[i] = alms(l,m).im;
if (l>real_lmax) real_lmax=l;
if (m>real_mmax) real_mmax=m;
++m;
if ((m>l) || (m>mmax)) { ++l; m=0; }
}
out.write_column(1,index,offset);
out.write_column(2,re,offset);
out.write_column(3,im,offset);
}
out.set_key("MAX-LPOL",real_lmax,"highest l in the table");
out.set_key("MAX-MPOL",real_mmax,"highest m in the table");
}
template void write_compressed_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<double> > &alms, int lmax,
int mmax, PDT datatype);
template void write_compressed_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<float> > &alms, int lmax,
int mmax, PDT datatype);

View file

@ -0,0 +1,123 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file alm_fitsio.h
* FITS I/O for spherical harmonic coefficients
*
* Copyright (C) 2003-2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_ALM_FITSIO_H
#define PLANCK_ALM_FITSIO_H
#include <string>
#include "xcomplex.h"
#include "datatypes.h"
#include "fitshandle.h"
template<typename T> class Alm;
/*! \defgroup alm_fitsio_group FITS-based I/O of a_lm */
/*! \{ */
/*! Returns the maximum \a l and \a m multipole moments found in the FITS HDU
pointed to be \a inp in \a lmax and \a mmax. */
void get_almsize(fitshandle &inp, int &lmax, int &mmax);
/*! Returns the maximum \a l and \a m multipole moments found in the HDU
\a hdunum of file \a filename in \a lmax and \a mmax. */
void get_almsize(const std::string &filename, int &lmax, int &mmax,
int hdunum=2);
/*! Returns the maximum \a l and \a m multipole moments found in the HDUs
2, 3 and 4 of file \a filename in \a lmax and \a mmax. */
void get_almsize_pol(const std::string &filename, int &lmax, int &mmax);
/*! Reads the a_lm of the FITS binary table pointed to by \a inp into
\a alms. \a alms is reallocated with the parameters \a lmax and \a mmax.
Values not present in the FITS table are set to zero; values outside
the requested (l,m) range are ignored. */
template<typename T> void read_Alm_from_fits
(fitshandle &inp, Alm<xcomplex<T> > &alms, int lmax, int mmax);
/*! Opens the FITS file \a filename, jumps to the HDU \a hdunum, then reads
the a_lm from the FITS binary table there into \a alms. \a alms is
reallocated with the parameters \a lmax and \a mmax.
Values not present in the FITS table are set to zero; values outside
the requested \a (l,m) range are ignored. */
template<typename T> void read_Alm_from_fits
(const std::string &filename, Alm<xcomplex<T> > &alms,
int lmax, int mmax, int hdunum=2);
template<typename T> inline void read_Alm_from_fits
(const std::string &filename, Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG, Alm<xcomplex<T> > &almC,
int lmax, int mmax, int firsthdu=2)
{
read_Alm_from_fits (filename, almT, lmax, mmax, firsthdu);
read_Alm_from_fits (filename, almG, lmax, mmax, firsthdu+1);
read_Alm_from_fits (filename, almC, lmax, mmax, firsthdu+2);
}
/*! Inserts a new binary table into \a out, which contains three columns
of type PLANCK_INT32, \a datatype and \a datatype, respectively.
The data in \a alms is written into this table; values outside
the requested (\a lmax, \a mmax) range are omitted. */
template<typename T> void write_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<T> > &alms,
int lmax, int mmax, PDT datatype);
template<typename T> inline void write_Alm_to_fits
(const std::string &outfile, const Alm<xcomplex<T> > &alms,
int lmax, int mmax, PDT datatype)
{
fitshandle out;
out.create(outfile);
write_Alm_to_fits (out, alms, lmax, mmax, datatype);
}
template<typename T> inline void write_Alm_to_fits
(const std::string &outfile, const Alm<xcomplex<T> > &almT,
const Alm<xcomplex<T> > &almG, const Alm<xcomplex<T> > &almC,
int lmax, int mmax, PDT datatype)
{
fitshandle out;
out.create(outfile);
write_Alm_to_fits (out, almT, lmax, mmax, datatype);
write_Alm_to_fits (out, almG, lmax, mmax, datatype);
write_Alm_to_fits (out, almC, lmax, mmax, datatype);
}
/*! Inserts a new binary table into \a out, which contains three columns
of type PLANCK_INT32, \a datatype and \a datatype, respectively.
The data in \a alms is written into this table; values outside
the requested (\a lmax, \a mmax) range are omitted. Values with an absolute
magnitude of zero are not written. */
template<typename T> void write_compressed_Alm_to_fits
(fitshandle &out, const Alm<xcomplex<T> > &alms,
int lmax, int mmax, PDT datatype);
/*! \} */
#endif

View file

@ -0,0 +1,428 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "alm_healpix_tools.h"
#include "alm.h"
#include "healpix_map.h"
#include "xcomplex.h"
#include "psht_cxx.h"
using namespace std;
template<typename T> void map2alm (const Healpix_Map<T> &map,
Alm<xcomplex<T> > &alm, const arr<double> &weight, bool add_alm)
{
planck_assert (map.Scheme()==RING, "map2alm: map must be in RING scheme");
planck_assert (int(weight.size())>=2*map.Nside(),
"map2alm: weight array has too few entries");
psht_joblist<T> joblist;
joblist.set_weighted_Healpix_geometry (map.Nside(),&weight[0]);
joblist.set_triangular_alm_info (alm.Lmax(), alm.Mmax());
joblist.add_map2alm(&map[0], &alm(0,0), add_alm);
joblist.execute();
}
template void map2alm (const Healpix_Map<float> &map,
Alm<xcomplex<float> > &alm, const arr<double> &weight,
bool add_alm);
template void map2alm (const Healpix_Map<double> &map,
Alm<xcomplex<double> > &alm, const arr<double> &weight,
bool add_alm);
template<typename T> void map2alm_iter (const Healpix_Map<T> &map,
Alm<xcomplex<T> > &alm, int num_iter, const arr<double> &weight)
{
map2alm(map,alm,weight);
for (int iter=1; iter<=num_iter; ++iter)
{
Healpix_Map<T> map2(map.Nside(),map.Scheme(),SET_NSIDE);
alm2map(alm,map2);
for (int m=0; m<map.Npix(); ++m)
map2[m] = map[m]-map2[m];
map2alm(map2,alm,weight,true);
}
}
template void map2alm_iter (const Healpix_Map<float> &map,
Alm<xcomplex<float> > &alm, int num_iter,
const arr<double> &weight);
template void map2alm_iter (const Healpix_Map<double> &map,
Alm<xcomplex<double> > &alm, int num_iter,
const arr<double> &weight);
template<typename T> void map2alm_iter2 (const Healpix_Map<T> &map,
Alm<xcomplex<T> > &alm, double err_abs, double err_rel)
{
double x_err_abs=1./err_abs, x_err_rel=1./err_rel;
arr<double> wgt(2*map.Nside());
wgt.fill(1);
Healpix_Map<T> map2(map);
alm.SetToZero();
while(true)
{
map2alm(map2,alm,wgt,true);
alm2map(alm,map2);
double errmeasure=0;
for (int m=0; m<map.Npix(); ++m)
{
double err = abs(map[m]-map2[m]);
double rel = (map[m]!=0) ? abs(err/map[m]) : 1e300;
errmeasure = max(errmeasure,min(err*x_err_abs,rel*x_err_rel));
map2[m] = map[m]-map2[m];
}
cout << "map error measure: " << errmeasure << endl;
if (errmeasure<1) break;
}
}
template void map2alm_iter2 (const Healpix_Map<double> &map,
Alm<xcomplex<double> > &alm, double err_abs, double err_rel);
template<typename T> void map2alm_spin
(const Healpix_Map<T> &map1, const Healpix_Map<T> &map2,
Alm<xcomplex<T> > &alm1, Alm<xcomplex<T> > &alm2,
int spin, const arr<double> &weight, bool add_alm)
{
planck_assert (map1.Scheme()==RING,
"map2alm_spin: maps must be in RING scheme");
planck_assert (map1.conformable(map2),
"map2alm_spin: maps are not conformable");
planck_assert (alm1.conformable(alm1),
"map2alm_spin: a_lm are not conformable");
planck_assert (int(weight.size())>=2*map1.Nside(),
"map2alm_spin: weight array has too few entries");
psht_joblist<T> joblist;
joblist.set_weighted_Healpix_geometry (map1.Nside(),&weight[0]);
joblist.set_triangular_alm_info (alm1.Lmax(), alm1.Mmax());
joblist.add_map2alm_spin(&map1[0], &map2[0], &alm1(0,0), &alm2(0,0),
spin, add_alm);
joblist.execute();
}
template void map2alm_spin
(const Healpix_Map<float> &map1, const Healpix_Map<float> &map2,
Alm<xcomplex<float> > &alm1, Alm<xcomplex<float> > &alm2,
int spin, const arr<double> &weight, bool add_alm);
template void map2alm_spin
(const Healpix_Map<double> &map1, const Healpix_Map<double> &map2,
Alm<xcomplex<double> > &alm1, Alm<xcomplex<double> > &alm2,
int spin, const arr<double> &weight, bool add_alm);
template<typename T> void map2alm_spin_iter2
(const Healpix_Map<T> &map1, const Healpix_Map<T> &map2,
Alm<xcomplex<T> > &alm1, Alm<xcomplex<T> > &alm2,
int spin, double err_abs, double err_rel)
{
arr<double> wgt(2*map1.Nside());
wgt.fill(1);
Healpix_Map<T> map1b(map1), map2b(map2);
alm1.SetToZero(); alm2.SetToZero();
while(true)
{
map2alm_spin(map1b,map2b,alm1,alm2,spin,wgt,true);
alm2map_spin(alm1,alm2,map1b,map2b,spin);
double errmeasure=0;
for (int m=0; m<map1.Npix(); ++m)
{
double err = abs(map1[m]-map1b[m]);
double rel = (map1[m]!=0) ? abs(err/map1[m]) : 1e300;
errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
map1b[m] = map1[m]-map1b[m];
err = abs(map2[m]-map2b[m]);
rel = (map2[m]!=0) ? abs(err/map2[m]) : 1e300;
errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
map2b[m] = map2[m]-map2b[m];
}
cout << "map error measure: " << errmeasure << endl;
if (errmeasure<1) break;
}
}
template void map2alm_spin_iter2
(const Healpix_Map<double> &map1, const Healpix_Map<double> &map2,
Alm<xcomplex<double> > &alm1, Alm<xcomplex<double> > &alm2,
int spin, double err_abs, double err_rel);
template<typename T> void map2alm_pol
(const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ,
const Healpix_Map<T> &mapU,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
const arr<double> &weight,
bool add_alm)
{
planck_assert (mapT.Scheme()==RING,
"map2alm_pol: maps must be in RING scheme");
planck_assert (mapT.conformable(mapQ) && mapT.conformable(mapU),
"map2alm_pol: maps are not conformable");
planck_assert (almT.conformable(almG) && almT.conformable(almC),
"map2alm_pol: a_lm are not conformable");
planck_assert (int(weight.size())>=2*mapT.Nside(),
"map2alm_pol: weight array has too few entries");
psht_joblist<T> joblist;
joblist.set_weighted_Healpix_geometry (mapT.Nside(),&weight[0]);
joblist.set_triangular_alm_info (almT.Lmax(), almT.Mmax());
joblist.add_map2alm_pol(&mapT[0], &mapQ[0], &mapU[0], &almT(0,0),
&almG(0,0), &almC(0,0), add_alm);
joblist.execute();
}
template void map2alm_pol
(const Healpix_Map<float> &mapT,
const Healpix_Map<float> &mapQ,
const Healpix_Map<float> &mapU,
Alm<xcomplex<float> > &almT,
Alm<xcomplex<float> > &almG,
Alm<xcomplex<float> > &almC,
const arr<double> &weight,
bool add_alm);
template void map2alm_pol
(const Healpix_Map<double> &mapT,
const Healpix_Map<double> &mapQ,
const Healpix_Map<double> &mapU,
Alm<xcomplex<double> > &almT,
Alm<xcomplex<double> > &almG,
Alm<xcomplex<double> > &almC,
const arr<double> &weight,
bool add_alm);
template<typename T> void map2alm_pol_iter
(const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ,
const Healpix_Map<T> &mapU,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
int num_iter,
const arr<double> &weight)
{
map2alm_pol(mapT,mapQ,mapU,almT,almG,almC,weight);
for (int iter=1; iter<=num_iter; ++iter)
{
Healpix_Map<T> mapT2(mapT.Nside(),mapT.Scheme(),SET_NSIDE),
mapQ2(mapT.Nside(),mapT.Scheme(),SET_NSIDE),
mapU2(mapT.Nside(),mapT.Scheme(),SET_NSIDE);
alm2map_pol(almT,almG,almC,mapT2,mapQ2,mapU2);
for (int m=0; m<mapT.Npix(); ++m)
{
mapT2[m] = mapT[m]-mapT2[m];
mapQ2[m] = mapQ[m]-mapQ2[m];
mapU2[m] = mapU[m]-mapU2[m];
}
map2alm_pol(mapT2,mapQ2,mapU2,almT,almG,almC,weight,true);
}
}
template void map2alm_pol_iter
(const Healpix_Map<float> &mapT,
const Healpix_Map<float> &mapQ,
const Healpix_Map<float> &mapU,
Alm<xcomplex<float> > &almT,
Alm<xcomplex<float> > &almG,
Alm<xcomplex<float> > &almC,
int num_iter,
const arr<double> &weight);
template void map2alm_pol_iter
(const Healpix_Map<double> &mapT,
const Healpix_Map<double> &mapQ,
const Healpix_Map<double> &mapU,
Alm<xcomplex<double> > &almT,
Alm<xcomplex<double> > &almG,
Alm<xcomplex<double> > &almC,
int num_iter,
const arr<double> &weight);
template<typename T> void map2alm_pol_iter2
(const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ,
const Healpix_Map<T> &mapU,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
double err_abs, double err_rel)
{
arr<double> wgt(2*mapT.Nside());
wgt.fill(1);
Healpix_Map<T> mapT2(mapT), mapQ2(mapQ), mapU2(mapU);
almT.SetToZero(); almG.SetToZero(); almC.SetToZero();
while(true)
{
map2alm_pol(mapT2,mapQ2,mapU2,almT,almG,almC,wgt,true);
alm2map_pol(almT,almG,almC,mapT2,mapQ2,mapU2);
double errmeasure=0;
for (int m=0; m<mapT.Npix(); ++m)
{
double err = abs(mapT[m]-mapT2[m]);
double rel = (mapT[m]!=0) ? abs(err/mapT[m]) : 1e300;
errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
mapT2[m] = mapT[m]-mapT2[m];
err = abs(mapQ[m]-mapQ2[m]);
rel = (mapQ[m]!=0) ? abs(err/mapQ[m]) : 1e300;
errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
mapQ2[m] = mapQ[m]-mapQ2[m];
err = abs(mapU[m]-mapU2[m]);
rel = (mapU[m]!=0) ? abs(err/mapU[m]) : 1e300;
errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
mapU2[m] = mapU[m]-mapU2[m];
}
cout << "map error measure: " << errmeasure << endl;
if (errmeasure<1) break;
}
}
template void map2alm_pol_iter2
(const Healpix_Map<double> &mapT,
const Healpix_Map<double> &mapQ,
const Healpix_Map<double> &mapU,
Alm<xcomplex<double> > &almT,
Alm<xcomplex<double> > &almG,
Alm<xcomplex<double> > &almC,
double err_abs, double err_rel);
template<typename T> void alm2map (const Alm<xcomplex<T> > &alm,
Healpix_Map<T> &map)
{
planck_assert (map.Scheme()==RING, "alm2map: map must be in RING scheme");
psht_joblist<T> joblist;
joblist.set_Healpix_geometry (map.Nside());
joblist.set_triangular_alm_info (alm.Lmax(), alm.Mmax());
joblist.add_alm2map(&alm(0,0), &map[0], false);
joblist.execute();
}
template void alm2map (const Alm<xcomplex<double> > &alm,
Healpix_Map<double> &map);
template void alm2map (const Alm<xcomplex<float> > &alm,
Healpix_Map<float> &map);
template<typename T> void alm2map_spin
(const Alm<xcomplex<T> > &alm1, const Alm<xcomplex<T> > &alm2,
Healpix_Map<T> &map1, Healpix_Map<T> &map2, int spin)
{
planck_assert (map1.Scheme()==RING,
"alm2map_spin: maps must be in RING scheme");
planck_assert (map1.conformable(map2),
"alm2map_spin: maps are not conformable");
planck_assert (alm1.conformable(alm2),
"alm2map_spin: a_lm are not conformable");
psht_joblist<T> joblist;
joblist.set_Healpix_geometry (map1.Nside());
joblist.set_triangular_alm_info (alm1.Lmax(), alm1.Mmax());
joblist.add_alm2map_spin(&alm1(0,0), &alm2(0,0), &map1[0], &map2[0],
spin, false);
joblist.execute();
}
template void alm2map_spin
(const Alm<xcomplex<double> > &alm1, const Alm<xcomplex<double> > &alm2,
Healpix_Map<double> &map, Healpix_Map<double> &map2, int spin);
template void alm2map_spin
(const Alm<xcomplex<float> > &alm1, const Alm<xcomplex<float> > &alm2,
Healpix_Map<float> &map, Healpix_Map<float> &map2, int spin);
template<typename T> void alm2map_pol
(const Alm<xcomplex<T> > &almT,
const Alm<xcomplex<T> > &almG,
const Alm<xcomplex<T> > &almC,
Healpix_Map<T> &mapT,
Healpix_Map<T> &mapQ,
Healpix_Map<T> &mapU)
{
planck_assert (mapT.Scheme()==RING,
"alm2map_pol: maps must be in RING scheme");
planck_assert (mapT.conformable(mapQ) && mapT.conformable(mapU),
"alm2map_pol: maps are not conformable");
planck_assert (almT.conformable(almG) && almT.conformable(almC),
"alm2map_pol: a_lm are not conformable");
psht_joblist<T> joblist;
joblist.set_Healpix_geometry (mapT.Nside());
joblist.set_triangular_alm_info (almT.Lmax(), almT.Mmax());
joblist.add_alm2map_pol(&almT(0,0), &almG(0,0), &almC(0,0), &mapT[0],
&mapQ[0], &mapU[0], false);
joblist.execute();
}
template void alm2map_pol (const Alm<xcomplex<double> > &almT,
const Alm<xcomplex<double> > &almG,
const Alm<xcomplex<double> > &almC,
Healpix_Map<double> &mapT,
Healpix_Map<double> &mapQ,
Healpix_Map<double> &mapU);
template void alm2map_pol (const Alm<xcomplex<float> > &almT,
const Alm<xcomplex<float> > &almG,
const Alm<xcomplex<float> > &almC,
Healpix_Map<float> &mapT,
Healpix_Map<float> &mapQ,
Healpix_Map<float> &mapU);
template<typename T> void alm2map_der1
(const Alm<xcomplex<T> > &alm,
Healpix_Map<T> &map,
Healpix_Map<T> &mapdth,
Healpix_Map<T> &mapdph)
{
planck_assert (map.Scheme()==RING,
"alm2map_der1: maps must be in RING scheme");
planck_assert (map.conformable(mapdth) && map.conformable(mapdph),
"alm2map_der1: maps are not conformable");
psht_joblist<T> joblist;
joblist.set_Healpix_geometry (map.Nside());
joblist.set_triangular_alm_info (alm.Lmax(), alm.Mmax());
joblist.add_alm2map(&alm(0,0), &map[0], false);
joblist.add_alm2map_der1(&alm(0,0), &mapdth[0], &mapdph[0], false);
joblist.execute();
}
template void alm2map_der1 (const Alm<xcomplex<double> > &alm,
Healpix_Map<double> &map,
Healpix_Map<double> &map_dth,
Healpix_Map<double> &map_dph);
template void alm2map_der1 (const Alm<xcomplex<float> > &alm,
Healpix_Map<float> &map,
Healpix_Map<float> &map_dth,
Healpix_Map<float> &map_dph);

View file

@ -0,0 +1,201 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file alm_healpix_tools.h
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef HEALPIX_ALM_HEALPIX_TOOLS_H
#define HEALPIX_ALM_HEALPIX_TOOLS_H
#include "xcomplex.h"
#include "arr.h"
template<typename T> class Alm;
template<typename T> class Healpix_Map;
/*! \defgroup alm_healpix_group Conversions between a_lm and HEALPix maps */
/*! \{ */
/*! Converts a Healpix map to a set of a_lms.
\param map the input map, which must have RING ordering
\param alm the output a_lms. l_max and m_max of the conversion are
determined from this object.
\param weight array containing the weights for the individual rings of
the map. It must have at least 2*\a map.Nside() entries.
\param add_alm If this is \a true, then the computed a_lm are added
to the values already residing in \a alm. */
template<typename T> void map2alm (const Healpix_Map<T> &map,
Alm<xcomplex<T> > &alm, const arr<double> &weight,
bool add_alm=false);
/*! Converts a Healpix map to a set of a_lms, using an iterative scheme
which is more accurate than plain map2alm().
\param map the input map, which must have RING ordering.
\param alm the output a_lms. l_max and m_max of the conversion are
determined from this object.
\param num_iter the number of iterations (0 is identical to map2alm()).
\param weight array containing the weights for the individual rings of
the map. It must have at least 2*\a map.Nside() entries. */
template<typename T> void map2alm_iter (const Healpix_Map<T> &map,
Alm<xcomplex<T> > &alm, int num_iter, const arr<double> &weight);
template<typename T> inline void map2alm_iter (const Healpix_Map<T> &map,
Alm<xcomplex<T> > &alm, int num_iter)
{
arr<double> wgt(2*map.Nside());
wgt.fill(1);
map2alm_iter(map,alm,num_iter,wgt);
}
template<typename T> void map2alm_iter2 (const Healpix_Map<T> &map,
Alm<xcomplex<T> > &alm, double err_abs, double err_rel);
template<typename T> void map2alm_spin
(const Healpix_Map<T> &map1, const Healpix_Map<T> &map2,
Alm<xcomplex<T> > &alm1, Alm<xcomplex<T> > &alm2,
int spin, const arr<double> &weight, bool add_alm);
template<typename T> void map2alm_spin_iter2
(const Healpix_Map<T> &map1, const Healpix_Map<T> &map2,
Alm<xcomplex<T> > &alm1, Alm<xcomplex<T> > &alm2,
int spin, double err_abs, double err_rel);
/*! Converts Healpix maps containing the I, Q and U Stokes parameters
to sets of a_lms.
\param mapT the I-Stokes parameter input map
\param mapQ the Q-Stokes parameter input map
\param mapU the U-Stokes parameter input map
\note All maps must have the same nside, and must be in RING scheme.
\param almT the output temperature a_lms
\param almG the output gradient a_lms
\param almC the output curl a_lms
\note all a_lm sets must have the the same lmax and mmax.
\param weight ring weights for the maps.
\param add_alm If this is \a true, then the computed a_lm are added
to the values already residing in \a alm.
\note The weight array must have at least 2*\a mapT.Nside() entries. */
template<typename T> void map2alm_pol
(const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ,
const Healpix_Map<T> &mapU,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
const arr<double> &weight,
bool add_alm=false);
/*! Converts Healpix maps containing the I, Q and U Stokes parameters
to sets of a_lms, using an iterative scheme which is more accurate than
plain map2alm_pol().
\param mapT the I-Stokes parameter input map
\param mapQ the Q-Stokes parameter input map
\param mapU the U-Stokes parameter input map
\note All maps must have the same nside, and must be in RING scheme.
\param almT the output temperature a_lms
\param almG the output gradient a_lms
\param almC the output curl a_lms
\note all a_lm sets must have the the same lmax and mmax.
\param num_iter the number of iterations (0 is identical to map2alm_pol()).
\param weight ring weights for the maps.
\note The weight array must have at least 2*\a mapT.Nside() entries. */
template<typename T> void map2alm_pol_iter
(const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ,
const Healpix_Map<T> &mapU,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
int num_iter,
const arr<double> &weight);
template<typename T> inline void map2alm_pol_iter
(const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ,
const Healpix_Map<T> &mapU,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
int num_iter)
{
arr<double> wgt(2*mapT.Nside());
wgt.fill(1);
map2alm_pol_iter(mapT,mapQ,mapU,almT,almG,almC,num_iter,wgt);
}
template<typename T> void map2alm_pol_iter2
(const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ,
const Healpix_Map<T> &mapU,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
double err_abs, double err_rel);
/*! Converts a a set of a_lm to a HEALPix map.
\param alm the input a_lms. l_max and m_max of the conversion are
determined from this object.
\param map the output map, which must have RING ordering. */
template<typename T> void alm2map (const Alm<xcomplex<T> > &alm,
Healpix_Map<T> &map);
template<typename T> void alm2map_spin
(const Alm<xcomplex<T> > &alm1, const Alm<xcomplex<T> > &alm2,
Healpix_Map<T> &map1, Healpix_Map<T> &map2, int spin);
/*! Converts a a set of polarised a_lm to a HEALPix map.
\param almT the input temperature a_lms
\param almG the input gradient a_lms
\param almC the input curl a_lms
\param mapT the I-Stokes parameter output map
\param mapQ the Q-Stokes parameter output map
\param mapU the U-Stokes parameter output map */
template<typename T> void alm2map_pol
(const Alm<xcomplex<T> > &almT,
const Alm<xcomplex<T> > &almG,
const Alm<xcomplex<T> > &almC,
Healpix_Map<T> &mapT,
Healpix_Map<T> &mapQ,
Healpix_Map<T> &mapU);
/*! Converts a a set of a_lm to a HEALPix map and its first derivatives.
\param alm the input a_lms. l_max and m_max of the conversion are
determined from this object.
\param map the output map, which must have RING ordering.
\param mapdth an output map containing \f$d (\mbox{map})/d\vartheta\f$,
which must have RING ordering.
\param mapdph an output map containing
\f$(\sin\vartheta)^{-1}d(\mbox{map})/d\varphi\f$,
which must have RING ordering. */
template<typename T> void alm2map_der1
(const Alm<xcomplex<T> > &alm,
Healpix_Map<T> &map,
Healpix_Map<T> &mapdth,
Healpix_Map<T> &mapdph);
/*! \} */
#endif

View file

@ -0,0 +1,450 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2011 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "alm_powspec_tools.h"
#include "alm.h"
#include "planck_rng.h"
#include "powspec.h"
#include "xcomplex.h"
#include "rotmatrix.h"
#include "openmp_support.h"
#include "wigner.h"
#include "lsconstants.h"
using namespace std;
template<typename T> void create_alm
(const PowSpec &powspec, Alm<xcomplex<T> > &alm, planck_rng &rng)
{
int lmax = alm.Lmax();
int mmax = alm.Mmax();
const double hsqrt2 = 1/sqrt(2.);
for (int l=0; l<=lmax; ++l)
{
double rms_tt = sqrt(powspec.tt(l));
double zeta1_r = rng.rand_gauss();
alm(l,0) = T(zeta1_r * rms_tt);
for (int m=1; m<=min(l,mmax); ++m)
{
zeta1_r = rng.rand_gauss()*hsqrt2;
double zeta1_i = rng.rand_gauss()*hsqrt2;
alm(l,m).Set (T(zeta1_r*rms_tt), T(zeta1_i*rms_tt));
}
}
}
template void create_alm (const PowSpec &powspec,
Alm<xcomplex<float> > &alm, planck_rng &rng);
template void create_alm (const PowSpec &powspec,
Alm<xcomplex<double> > &alm, planck_rng &rng);
template<typename T> void create_alm_pol
(const PowSpec &powspec,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
planck_rng &rng)
{
int lmax = almT.Lmax();
int mmax = almT.Mmax();
const double hsqrt2 = 1/sqrt(2.);
for (int l=0; l<=lmax; ++l)
{
double rms_tt=0, rms_g1=0;
if (powspec.tt(l) != 0)
{
rms_tt = sqrt(powspec.tt(l));
rms_g1 = powspec.tg(l)/rms_tt;
}
double zeta1_r = rng.rand_gauss();
almT(l,0) = T(zeta1_r * rms_tt);
almG(l,0) = T(zeta1_r * rms_g1);
for (int m=1; m<=min(l,mmax); ++m)
{
zeta1_r = rng.rand_gauss()*hsqrt2;
double zeta1_i = rng.rand_gauss()*hsqrt2;
almT(l,m).Set (T(zeta1_r*rms_tt), T(zeta1_i*rms_tt));
almG(l,m).Set (T(zeta1_r*rms_g1), T(zeta1_i*rms_g1));
}
}
for (int l=0; l<=lmax; ++l)
{
double rms_g2 = 0;
double rms_cc = 0;
if (powspec.tt(l) != 0)
{
rms_g2 = powspec.gg(l) - (powspec.tg(l)/powspec.tt(l))*powspec.tg(l);
if (rms_g2 <= 0)
{
planck_assert (abs(rms_g2) <= 1e-8*abs(powspec.gg(l)),
"Inconsistent TT, GG and TG spectra at l="+dataToString(l));
rms_g2 = 0;
}
rms_g2 = sqrt(rms_g2);
rms_cc = sqrt(powspec.cc(l));
}
almG(l,0) += T(rng.rand_gauss()*rms_g2);
almC(l,0) = T(rng.rand_gauss()*rms_cc);
for (int m=1; m<=min(l,mmax); ++m)
{
double zeta2_r = rng.rand_gauss()*hsqrt2;
double zeta2_i = rng.rand_gauss()*hsqrt2;
double zeta3_r = rng.rand_gauss()*hsqrt2;
double zeta3_i = rng.rand_gauss()*hsqrt2;
almG(l,m) += xcomplex<T> (T(zeta2_r*rms_g2),T(zeta2_i*rms_g2));
almC(l,m).Set (T(zeta3_r*rms_cc),T(zeta3_i*rms_cc));
}
}
}
template void create_alm_pol
(const PowSpec &powspec,
Alm<xcomplex<float> > &almT,
Alm<xcomplex<float> > &almG,
Alm<xcomplex<float> > &almC,
planck_rng &rng);
template void create_alm_pol
(const PowSpec &powspec,
Alm<xcomplex<double> > &almT,
Alm<xcomplex<double> > &almG,
Alm<xcomplex<double> > &almC,
planck_rng &rng);
template<typename T> void extract_crosspowspec
(const Alm<xcomplex<T> > &alm1,
const Alm<xcomplex<T> > &alm2,PowSpec &powspec)
{
planck_assert (alm1.conformable(alm2), "a_lm are not conformable");
arr<double> tt(alm1.Lmax()+1);
for (int l=0; l<=alm1.Lmax(); ++l)
{
tt[l] = alm1(l,0).re*alm2(l,0).re;
int limit = min(l,alm1.Mmax());
for (int m=1; m<=limit; ++m)
tt[l] += 2 * (alm1(l,m).re*alm2(l,m).re + alm1(l,m).im*alm2(l,m).im);
tt[l] /= (2*l+1);
}
powspec.Set(tt);
}
template void extract_crosspowspec
(const Alm<xcomplex<float> > &alm1,
const Alm<xcomplex<float> > &alm2, PowSpec &powspec);
template void extract_crosspowspec
(const Alm<xcomplex<double> > &alm1,
const Alm<xcomplex<double> > &alm2, PowSpec &powspec);
template<typename T> void extract_powspec
(const Alm<xcomplex<T> > &alm, PowSpec &powspec)
{ extract_crosspowspec (alm,alm,powspec); }
template void extract_powspec
(const Alm<xcomplex<float> > &alm, PowSpec &powspec);
template void extract_powspec
(const Alm<xcomplex<double> > &alm, PowSpec &powspec);
namespace {
template<typename T> void extract_crosspowspec
(const Alm<xcomplex<T> > &almT1,
const Alm<xcomplex<T> > &almG1,
const Alm<xcomplex<T> > &almC1,
const Alm<xcomplex<T> > &almT2,
const Alm<xcomplex<T> > &almG2,
const Alm<xcomplex<T> > &almC2,
PowSpec &powspec)
{
planck_assert (almT1.conformable(almG1) && almT1.conformable(almC1) &&
almT1.conformable(almT2) && almT1.conformable(almG2) &&
almT1.conformable(almC2), "a_lm are not conformable");
int lmax = almT1.Lmax();
arr<double> tt(lmax+1), gg(lmax+1), cc(lmax+1), tg(lmax+1),
tc(lmax+1), gc(lmax+1);
for (int l=0; l<=lmax; ++l)
{
tt[l] = almT1(l,0).re*almT2(l,0).re;
gg[l] = almG1(l,0).re*almG2(l,0).re;
cc[l] = almC1(l,0).re*almC2(l,0).re;
tg[l] = almT1(l,0).re*almG2(l,0).re;
tc[l] = almT1(l,0).re*almC2(l,0).re;
gc[l] = almG1(l,0).re*almC2(l,0).re;
int limit = min(l,almT1.Mmax());
for (int m=1; m<=limit; ++m)
{
tt[l] += 2 * (almT1(l,m).re*almT2(l,m).re + almT1(l,m).im*almT2(l,m).im);
gg[l] += 2 * (almG1(l,m).re*almG2(l,m).re + almG1(l,m).im*almG2(l,m).im);
cc[l] += 2 * (almC1(l,m).re*almC2(l,m).re + almC1(l,m).im*almC2(l,m).im);
tg[l] += 2 * (almT1(l,m).re*almG2(l,m).re + almT1(l,m).im*almG2(l,m).im);
tc[l] += 2 * (almT1(l,m).re*almC2(l,m).re + almT1(l,m).im*almC2(l,m).im);
gc[l] += 2 * (almG1(l,m).re*almC2(l,m).re + almG1(l,m).im*almC2(l,m).im);
}
tt[l] /= (2*l+1);
gg[l] /= (2*l+1);
cc[l] /= (2*l+1);
tg[l] /= (2*l+1);
tc[l] /= (2*l+1);
gc[l] /= (2*l+1);
}
powspec.Set(tt,gg,cc,tg,tc,gc);
}
} // unnamed namespace
template<typename T> void extract_powspec
(const Alm<xcomplex<T> > &almT,
const Alm<xcomplex<T> > &almG,
const Alm<xcomplex<T> > &almC,
PowSpec &powspec)
{ extract_crosspowspec(almT,almG,almC,almT,almG,almC,powspec); }
template void extract_powspec
(const Alm<xcomplex<float> > &almT,
const Alm<xcomplex<float> > &almG,
const Alm<xcomplex<float> > &almC,
PowSpec &powspec);
template void extract_powspec
(const Alm<xcomplex<double> > &almT,
const Alm<xcomplex<double> > &almG,
const Alm<xcomplex<double> > &almC,
PowSpec &powspec);
template<typename T> void smoothWithGauss
(Alm<xcomplex<T> > &alm, double fwhm)
{
int fct = (fwhm>=0) ? 1 : -1;
double sigma = fwhm*fwhm2sigma;
arr<double> gb(alm.Lmax()+1);
for (int l=0; l<=alm.Lmax(); ++l)
gb[l] = exp(-.5*fct*l*(l+1)*sigma*sigma);
alm.ScaleL(gb);
}
template void smoothWithGauss
(Alm<xcomplex<float> > &alm, double fwhm);
template void smoothWithGauss
(Alm<xcomplex<double> > &alm, double fwhm);
template<typename T> void smoothWithGauss
(Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
double fwhm)
{
int fct = (fwhm>=0) ? 1 : -1;
double sigma = fwhm*fwhm2sigma;
double fact_pol = exp(2*fct*sigma*sigma);
arr<double> gb(almT.Lmax()+1);
for (int l=0; l<=almT.Lmax(); ++l)
gb[l] = exp(-.5*fct*l*(l+1)*sigma*sigma);
almT.ScaleL(gb);
for (int l=0; l<=almT.Lmax(); ++l)
gb[l] *= fact_pol;
almG.ScaleL(gb); almC.ScaleL(gb);
}
template void smoothWithGauss
(Alm<xcomplex<float> > &almT,
Alm<xcomplex<float> > &almG,
Alm<xcomplex<float> > &almC,
double fwhm);
template void smoothWithGauss
(Alm<xcomplex<double> > &almT,
Alm<xcomplex<double> > &almG,
Alm<xcomplex<double> > &almC,
double fwhm);
template<typename T> void rotate_alm (Alm<xcomplex<T> > &alm,
double psi, double theta, double phi)
{
planck_assert (alm.Lmax()==alm.Mmax(),
"rotate_alm: lmax must be equal to mmax");
int lmax=alm.Lmax();
arr<xcomplex<double> > exppsi(lmax+1), expphi(lmax+1);
for (int m=0; m<=lmax; ++m)
{
exppsi[m].Set (cos(psi*m),-sin(psi*m));
expphi[m].Set (cos(phi*m),-sin(phi*m));
}
wigner_d_risbo_openmp rec(lmax,theta);
arr<xcomplex<double> > almtmp(lmax+1);
for (int l=0; l<=lmax; ++l)
{
const arr2<double> &d(rec.recurse());
for (int m=0; m<=l; ++m)
almtmp[m] = xcomplex<double>(alm(l,0))*d[l][l+m];
#pragma omp parallel
{
int64 lo,hi;
openmp_calc_share(0,l+1,lo,hi);
bool flip = true;
for (int mm=1; mm<=l; ++mm)
{
xcomplex<double> t1 = xcomplex<double>(alm(l,mm))*exppsi[mm];
bool flip2 = ((mm+lo)&1) ? true : false;
for (int m=lo; m<hi; ++m)
{
double d1 = flip2 ? -d[l-mm][l-m] : d[l-mm][l-m];
double d2 = flip ? -d[l-mm][l+m] : d[l-mm][l+m];
double f1 = d1+d2, f2 = d1-d2;
almtmp[m].re += t1.re*f1; almtmp[m].im += t1.im*f2;
flip2 = !flip2;
}
flip = !flip;
}
}
for (int m=0; m<=l; ++m)
alm(l,m) = xcomplex<T>(almtmp[m]*expphi[m]);
}
}
template void rotate_alm (Alm<xcomplex<float> > &alm,
double psi, double theta, double phi);
template void rotate_alm (Alm<xcomplex<double> > &alm,
double psi, double theta, double phi);
template<typename T> void rotate_alm (Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG, Alm<xcomplex<T> > &almC,
double psi, double theta, double phi)
{
planck_assert (almT.Lmax()==almT.Mmax(),
"rotate_alm: lmax must be equal to mmax");
planck_assert (almG.conformable(almT) && almC.conformable(almT),
"rotate_alm: a_lm are not conformable");
int lmax=almT.Lmax();
arr<xcomplex<double> > exppsi(lmax+1), expphi(lmax+1);
for (int m=0; m<=lmax; ++m)
{
exppsi[m].Set (cos(psi*m),-sin(psi*m));
expphi[m].Set (cos(phi*m),-sin(phi*m));
}
wigner_d_risbo_openmp rec(lmax,theta);
arr<xcomplex<double> > almtmpT(lmax+1), almtmpG(lmax+1), almtmpC(lmax+1);
for (int l=0; l<=lmax; ++l)
{
const arr2<double> &d(rec.recurse());
for (int m=0; m<=l; ++m)
{
almtmpT[m] = xcomplex<double>(almT(l,0))*d[l][m+l];
almtmpG[m] = xcomplex<double>(almG(l,0))*d[l][m+l];
almtmpC[m] = xcomplex<double>(almC(l,0))*d[l][m+l];
}
#pragma omp parallel
{
int64 lo,hi;
openmp_calc_share(0,l+1,lo,hi);
bool flip = true;
for (int mm=1; mm<=l; ++mm)
{
xcomplex<double> t1T = xcomplex<double>(almT(l,mm))*exppsi[mm];
xcomplex<double> t1G = xcomplex<double>(almG(l,mm))*exppsi[mm];
xcomplex<double> t1C = xcomplex<double>(almC(l,mm))*exppsi[mm];
bool flip2 = ((mm+lo)&1) ? true : false;
for (int m=lo; m<hi; ++m)
{
double d1 = flip2 ? -d[l-mm][l-m] : d[l-mm][l-m];
double d2 = flip ? -d[l-mm][l+m] : d[l-mm][l+m];
double f1 = d1+d2, f2 = d1-d2;
almtmpT[m].re += t1T.re*f1; almtmpT[m].im += t1T.im*f2;
almtmpG[m].re += t1G.re*f1; almtmpG[m].im += t1G.im*f2;
almtmpC[m].re += t1C.re*f1; almtmpC[m].im += t1C.im*f2;
flip2 = !flip2;
}
flip = !flip;
}
}
for (int m=0; m<=l; ++m)
{
almT(l,m) = xcomplex<T>(almtmpT[m]*expphi[m]);
almG(l,m) = xcomplex<T>(almtmpG[m]*expphi[m]);
almC(l,m) = xcomplex<T>(almtmpC[m]*expphi[m]);
}
}
}
template void rotate_alm (Alm<xcomplex<float> > &almT,
Alm<xcomplex<float> > &almG, Alm<xcomplex<float> > &almC,
double psi, double theta, double phi);
template void rotate_alm (Alm<xcomplex<double> > &almT,
Alm<xcomplex<double> > &almG, Alm<xcomplex<double> > &almC,
double psi, double theta, double phi);
template<typename T> void rotate_alm (Alm<xcomplex<T> > &alm,
const rotmatrix &mat)
{
double a1, a2, a3;
mat.Extract_CPAC_Euler_Angles (a1, a2, a3);
rotate_alm (alm, a3, a2, a1);
}
template void rotate_alm (Alm<xcomplex<float> > &alm, const rotmatrix &mat);
template void rotate_alm (Alm<xcomplex<double> > &alm, const rotmatrix &mat);
template<typename T> void rotate_alm (Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG, Alm<xcomplex<T> > &almC,
const rotmatrix &mat)
{
double a1, a2, a3;
mat.Extract_CPAC_Euler_Angles (a1, a2, a3);
rotate_alm (almT, almG, almC, a3, a2, a1);
}
template void rotate_alm (Alm<xcomplex<float> > &almT,
Alm<xcomplex<float> > &almG, Alm<xcomplex<float> > &almC,
const rotmatrix &mat);
template void rotate_alm (Alm<xcomplex<double> > &almT,
Alm<xcomplex<double> > &almG, Alm<xcomplex<double> > &almC,
const rotmatrix &mat);

View file

@ -0,0 +1,125 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file alm_powspec_tools.h
* Copyright (C) 2003, 2004, 2005 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_ALM_POWSPEC_TOOLS_H
#define PLANCK_ALM_POWSPEC_TOOLS_H
#include "xcomplex.h"
template<typename T> class Alm;
class PowSpec;
class planck_rng;
class rotmatrix;
/*! \defgroup alm_ps_group Conversions between a_lm and power spectra */
/*! \{ */
/*! Creates a Gaussian realisation of the input power spectrum \a powspec,
using the random number generator \a rng, and returns the result
in \a alm. */
template<typename T> void create_alm (const PowSpec &powspec,
Alm<xcomplex<T> > &alm, planck_rng &rng);
/*! Creates a Gaussian realisation of the polarised input power spectrum
\a powspec, using the random number generator \a rng, and returns the
result in \a almT, \a almG and \a almC. */
template<typename T> void create_alm_pol
(const PowSpec &powspec,
Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
planck_rng &rng);
/*! Returns the unpolarised power spectrum of \a alm in \a powspec. */
template<typename T> void extract_powspec
(const Alm<xcomplex<T> > &alm, PowSpec &powspec);
/*! Returns the cross power spectrum of \a alm1 and \a alm2 in \a powspec. */
template<typename T> void extract_crosspowspec
(const Alm<xcomplex<T> > &alm1,
const Alm<xcomplex<T> > &alm2, PowSpec &powspec);
/*! Returns the polarised power spectrum of \a almT, \a almG and \a almC
in \a powspec. */
template<typename T> void extract_powspec
(const Alm<xcomplex<T> > &almT,
const Alm<xcomplex<T> > &almG,
const Alm<xcomplex<T> > &almC,
PowSpec &powspec);
/*! \} */
/*! Applies a convolution with a Gaussian beam with an FWHM of
\a fwhm (in radian) to \a alm.
\note If \a fwhm<0, a deconvolution with \a -fwhm is performed.
\relates Alm */
template<typename T> void smoothWithGauss
(Alm<xcomplex<T> > &alm, double fwhm);
/*! Applies a convolution with a Gaussian beam with an FWHM of
\a fwhm (in radian) to \a almT, \a almG and \a almC.
\note If \a fwhm<0, a deconvolution with \a -fwhm is performed.
\relates Alm */
template<typename T> void smoothWithGauss
(Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG,
Alm<xcomplex<T> > &almC,
double fwhm);
/*! Rotates \a alm through the Euler angles \a psi, \a theta and \a phi.
The Euler angle convention is right handed, rotations are active.
- \a psi is the first rotation about the z-axis (vertical)
- then \a theta about the ORIGINAL (unrotated) y-axis
- then \a phi about the ORIGINAL (unrotated) z-axis (vertical)
\relates Alm */
template<typename T> void rotate_alm (Alm<xcomplex<T> > &alm,
double psi, double theta, double phi);
/*! Rotates \a almT, \a almG and \a almC through the Euler angles
\a psi, \a theta and \a phi.
The Euler angle convention is right handed, rotations are active.
- \a psi is the first rotation about the z-axis (vertical)
- then \a theta about the ORIGINAL (unrotated) y-axis
- then \a phi about the ORIGINAL (unrotated) z-axis (vertical)
\relates Alm */
template<typename T> void rotate_alm (Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG, Alm<xcomplex<T> > &almC,
double psi, double theta, double phi);
/*! Rotates \a alm through the rotation matrix \a mat.
\relates Alm */
template<typename T> void rotate_alm (Alm<xcomplex<T> > &alm,
const rotmatrix &mat);
/*! Rotates \a almT, \a almG and \a almC through the rotation matrix \a mat.
\relates Alm */
template<typename T> void rotate_alm (Alm<xcomplex<T> > &almT,
Alm<xcomplex<T> > &almG, Alm<xcomplex<T> > &almC,
const rotmatrix &mat);
#endif

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
anafast_cxx_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,41 @@
Parameters read by anafast_cxx:
nlmax (integer):
maximum order of l
nmmax (integer):
maximum order of m (must not be larger than nlmax, default=nlmax)
infile (string):
input file containing the Healpix map
outfile (string, default=""):
output file name for power spectrum; if empty, no spectrum is written
outfile_alms (string, default=""):
output file name for the a_lm; if empty, no a_lm are written
polarisation (bool):
if false, only the intensity a_lm are generated,
if true, a_lm for T, G and C component are generated
weighted (bool, default=false):
if true, weighted quadrature is used
if (weighted)
healpix_data (string):
directory containing the Healpix data files
endif
iter_order (integer, default=0)
number of iterations for the analysis (0: standard analysis)
double_precision (bool, default=false):
if false, maps and a_lm are read/written in single precision,
otherwise in double precision.
if (polarisation==true && outfile!="")
full_powerspectrum (bool, default=false):
if true, write a 6-column power spectrum;
if false, write a 4-column power spectrum.
endif

View file

@ -0,0 +1,129 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "xcomplex.h"
#include "cxxutils.h"
#include "paramfile.h"
#include "healpix_data_io.h"
#include "alm.h"
#include "alm_fitsio.h"
#include "healpix_map.h"
#include "healpix_map_fitsio.h"
#include "powspec.h"
#include "powspec_fitsio.h"
#include "alm_healpix_tools.h"
#include "alm_powspec_tools.h"
#include "fitshandle.h"
#include "levels_facilities.h"
#include "lsconstants.h"
using namespace std;
namespace {
template<typename T> void anafast_cxx (paramfile &params)
{
int nlmax = params.template find<int>("nlmax");
int nmmax = params.template find<int>("nmmax",nlmax);
string infile = params.template find<string>("infile");
string outfile = params.template find<string>("outfile","");
string outfile_alms = params.template find<string>("outfile_alms","");
planck_assert ((outfile!="") || (outfile_alms!=""),
"no output specified, nothing done");
bool polarisation = params.template find<bool>("polarisation");
int num_iter = params.template find<int>("iter_order",0);
if (!polarisation)
{
Healpix_Map<T> map;
read_Healpix_map_from_fits(infile,map,1,2);
arr<double> weight;
get_ring_weights (params,map.Nside(),weight);
Alm<xcomplex<T> > alm(nlmax,nmmax);
double avg=map.average();
map.Add(T(-avg));
if (map.Scheme()==NEST) map.swap_scheme();
map2alm_iter(map,alm,num_iter,weight);
alm(0,0) += T(avg*sqrt(fourpi));
if (outfile!="")
{
PowSpec powspec;
extract_powspec (alm,powspec);
write_powspec_to_fits (outfile,powspec,1);
}
if (outfile_alms!="")
write_Alm_to_fits(outfile_alms,alm,nlmax,nmmax,planckType<T>());
}
else
{
Healpix_Map<T> mapT, mapQ, mapU;
read_Healpix_map_from_fits(infile,mapT,mapQ,mapU,2);
arr<double> weight;
get_ring_weights (params,mapT.Nside(),weight);
Alm<xcomplex<T> > almT(nlmax,nmmax), almG(nlmax,nmmax), almC(nlmax,nmmax);
double avg=mapT.average();
mapT.Add(T(-avg));
if (mapT.Scheme()==NEST) mapT.swap_scheme();
if (mapQ.Scheme()==NEST) mapQ.swap_scheme();
if (mapU.Scheme()==NEST) mapU.swap_scheme();
map2alm_pol_iter
(mapT,mapQ,mapU,almT,almG,almC,num_iter,weight);
almT(0,0) += T(avg*sqrt(fourpi));
if (outfile!="")
{
PowSpec powspec;
extract_powspec (almT,almG,almC,powspec);
params.template find<bool>("full_powerspectrum",false) ?
write_powspec_to_fits (outfile,powspec,6) :
write_powspec_to_fits (outfile,powspec,4);
}
if (outfile_alms!="")
write_Alm_to_fits (outfile_alms,almT,almG,almC,nlmax,nmmax,planckType<T>());
}
}
} // unamed namespace
int anafast_cxx_module (int argc, const char **argv)
{
module_startup ("anafast_cxx", argc, argv, 2, "<parameter file>");
paramfile params (argv[1]);
bool dp = params.find<bool> ("double_precision",false);
dp ? anafast_cxx<double>(params) : anafast_cxx<float>(params);
return 0;
}

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
calc_powspec_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,73 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2004-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "fitshandle.h"
#include "alm.h"
#include "alm_fitsio.h"
#include "powspec.h"
#include "powspec_fitsio.h"
#include "alm_powspec_tools.h"
#include "levels_facilities.h"
using namespace std;
int calc_powspec_module (int argc, const char **argv)
{
announce ("calc_powspec");
planck_assert (argc==3||argc==4,
"usage: calc_powspec <almfile1> [<almfile2>] <powspec_file>");
if (argc==3)
{
int lmax,mmax;
get_almsize(argv[1],lmax,mmax,2);
Alm<xcomplex<float> > alm;
read_Alm_from_fits (argv[1],alm,lmax,mmax,2);
PowSpec powspec;
extract_powspec (alm,powspec);
write_powspec_to_fits (argv[2],powspec,1);
}
else
{
int lmax,mmax;
get_almsize(argv[1],lmax,mmax,2);
Alm<xcomplex<float> > alm1;
read_Alm_from_fits (argv[1],alm1,lmax,mmax,2);
get_almsize(argv[2],lmax,mmax,2);
Alm<xcomplex<float> > alm2;
read_Alm_from_fits (argv[2],alm2,lmax,mmax,2);
PowSpec powspec;
extract_crosspowspec (alm1,alm2,powspec);
write_powspec_to_fits (argv[3],powspec,1);
}
return 0;
}

View file

@ -0,0 +1,798 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "healpix_base.h"
#include "cxxutils.h"
#include "pointing.h"
#include "arr.h"
#include "geom_utils.h"
#include "lsconstants.h"
using namespace std;
short Healpix_Base::ctab[];
short Healpix_Base::utab[];
const nside_dummy SET_NSIDE=nside_dummy();
Healpix_Ordering_Scheme string2HealpixScheme (const string &inp)
{
string tmp=trim(inp);
if (equal_nocase(tmp,"RING")) return RING;
if (equal_nocase(tmp,"NESTED")) return NEST;
planck_fail ("bad Healpix ordering scheme '"+tmp+
"': expected 'RING' or 'NESTED'");
}
Healpix_Base::Tablefiller::Tablefiller()
{
for (int m=0; m<0x100; ++m)
{
ctab[m] = short(
(m&0x1 ) | ((m&0x2 ) << 7) | ((m&0x4 ) >> 1) | ((m&0x8 ) << 6)
| ((m&0x10) >> 2) | ((m&0x20) << 5) | ((m&0x40) >> 3) | ((m&0x80) << 4));
utab[m] = short(
(m&0x1 ) | ((m&0x2 ) << 1) | ((m&0x4 ) << 2) | ((m&0x8 ) << 3)
| ((m&0x10) << 4) | ((m&0x20) << 5) | ((m&0x40) << 6) | ((m&0x80) << 7));
}
}
Healpix_Base::Tablefiller Healpix_Base::Filler;
const int Healpix_Base::jrll[] = { 2,2,2,2,3,3,3,3,4,4,4,4 };
const int Healpix_Base::jpll[] = { 1,3,5,7,0,2,4,6,1,3,5,7 };
int Healpix_Base::npix2nside (int npix)
{
int res=isqrt(npix/12);
planck_assert (npix==res*res*12, "npix2nside: invalid argument");
return res;
}
int Healpix_Base::ring_above (double z) const
{
double az=abs(z);
if (az>twothird) // polar caps
{
int iring = int(nside_*sqrt(3*(1-az)));
return (z>0) ? iring : 4*nside_-iring-1;
}
else // ----- equatorial region ---------
return int(nside_*(2-1.5*z));
}
void Healpix_Base::in_ring(int iz, double phi0, double dphi,
vector<int> &listir) const
{
int nr, ir, ipix1;
double shift=0.5;
if (iz<nside_) // north pole
{
ir = iz;
nr = ir*4;
ipix1 = 2*ir*(ir-1); // lowest pixel number in the ring
}
else if (iz>(3*nside_)) // south pole
{
ir = 4*nside_ - iz;
nr = ir*4;
ipix1 = npix_ - 2*ir*(ir+1); // lowest pixel number in the ring
}
else // equatorial region
{
ir = iz - nside_ + 1; // within {1, 2*nside + 1}
nr = nside_*4;
if ((ir&1)==0) shift = 0;
ipix1 = ncap_ + (ir-1)*nr; // lowest pixel number in the ring
}
int ipix2 = ipix1 + nr - 1; // highest pixel number in the ring
// ----------- constructs the pixel list --------------
if (dphi > (pi-1e-7))
for (int i=ipix1; i<=ipix2; ++i) listir.push_back(i);
else
{
int ip_lo = ifloor<int>(nr*inv_twopi*(phi0-dphi) - shift)+1;
int ip_hi = ifloor<int>(nr*inv_twopi*(phi0+dphi) - shift);
int pixnum = ip_lo+ipix1;
if (pixnum<ipix1) pixnum += nr;
for (int i=ip_lo; i<=ip_hi; ++i, ++pixnum)
{
if (pixnum>ipix2) pixnum -= nr;
listir.push_back(pixnum);
}
}
}
void Healpix_Base::nest2xyf (int pix, int &ix, int &iy, int &face_num) const
{
face_num = pix>>(2*order_);
pix &= (npface_-1);
int raw = (pix&0x5555) | ((pix&0x55550000)>>15);
ix = ctab[raw&0xff] | (ctab[raw>>8]<<4);
pix >>= 1;
raw = (pix&0x5555) | ((pix&0x55550000)>>15);
iy = ctab[raw&0xff] | (ctab[raw>>8]<<4);
}
int Healpix_Base::xyf2nest (int ix, int iy, int face_num) const
{
return (face_num<<(2*order_)) +
(utab[ix&0xff] | (utab[ix>>8]<<16)
| (utab[iy&0xff]<<1) | (utab[iy>>8]<<17));
}
void Healpix_Base::ring2xyf (int pix, int &ix, int &iy, int &face_num) const
{
int iring, iphi, kshift, nr;
int nl2 = 2*nside_;
if (pix<ncap_) // North Polar cap
{
iring = int(0.5*(1+isqrt(1+2*pix))); //counted from North pole
iphi = (pix+1) - 2*iring*(iring-1);
kshift = 0;
nr = iring;
face_num=0;
int tmp = iphi-1;
if (tmp>=(2*iring))
{
face_num=2;
tmp-=2*iring;
}
if (tmp>=iring) ++face_num;
}
else if (pix<(npix_-ncap_)) // Equatorial region
{
int ip = pix - ncap_;
if (order_>=0)
{
iring = (ip>>(order_+2)) + nside_; // counted from North pole
iphi = (ip&(4*nside_-1)) + 1;
}
else
{
iring = (ip/(4*nside_)) + nside_; // counted from North pole
iphi = (ip%(4*nside_)) + 1;
}
kshift = (iring+nside_)&1;
nr = nside_;
unsigned int ire = iring-nside_+1;
unsigned int irm = nl2+2-ire;
int ifm, ifp;
if (order_>=0)
{
ifm = (iphi - ire/2 + nside_ -1) >> order_;
ifp = (iphi - irm/2 + nside_ -1) >> order_;
}
else
{
ifm = (iphi - ire/2 + nside_ -1) / nside_;
ifp = (iphi - irm/2 + nside_ -1) / nside_;
}
if (ifp == ifm) // faces 4 to 7
face_num = (ifp==4) ? 4 : ifp+4;
else if (ifp<ifm) // (half-)faces 0 to 3
face_num = ifp;
else // (half-)faces 8 to 11
face_num = ifm + 8;
}
else // South Polar cap
{
int ip = npix_ - pix;
iring = int(0.5*(1+isqrt(2*ip-1))); //counted from South pole
iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
kshift = 0;
nr = iring;
iring = 2*nl2-iring;
face_num=8;
int tmp = iphi-1;
if (tmp>=(2*nr))
{
face_num=10;
tmp-=2*nr;
}
if (tmp>=nr) ++face_num;
}
int irt = iring - (jrll[face_num]*nside_) + 1;
int ipt = 2*iphi- jpll[face_num]*nr - kshift -1;
if (ipt>=nl2) ipt-=8*nside_;
ix = (ipt-irt) >>1;
iy =(-(ipt+irt))>>1;
}
int Healpix_Base::xyf2ring (int ix, int iy, int face_num) const
{
int nl4 = 4*nside_;
int jr = (jrll[face_num]*nside_) - ix - iy - 1;
int nr, kshift, n_before;
if (jr<nside_)
{
nr = jr;
n_before = 2*nr*(nr-1);
kshift = 0;
}
else if (jr > 3*nside_)
{
nr = nl4-jr;
n_before = npix_ - 2*(nr+1)*nr;
kshift = 0;
}
else
{
nr = nside_;
n_before = ncap_ + (jr-nside_)*nl4;
kshift = (jr-nside_)&1;
}
int jp = (jpll[face_num]*nr + ix - iy + 1 + kshift) / 2;
if (jp>nl4)
jp-=nl4;
else
if (jp<1) jp+=nl4;
return n_before + jp - 1;
}
double Healpix_Base::ring2z (int ring) const
{
if (ring<nside_)
return 1 - ring*ring*fact2_;
if (ring <=3*nside_)
return (2*nside_-ring)*fact1_;
ring=4*nside_ - ring;
return ring*ring*fact2_ - 1;
}
int Healpix_Base::pix2ring (int pix) const
{
if (scheme_==RING)
{
if (pix<ncap_) // North Polar cap
return int(0.5*(1+isqrt(1+2*pix))); //counted from North pole
else if (pix<(npix_-ncap_)) // Equatorial region
{
int ip = pix - ncap_;
return ip/(4*nside_) + nside_; // counted from North pole
}
else // South Polar cap
{
int ip = npix_ - pix;
return 4*nside_ - int(0.5*(1+isqrt(2*ip-1))); //counted from South pole
}
}
else
{
int face_num, ix, iy;
nest2xyf(pix,ix,iy,face_num);
return (jrll[face_num]<<order_) - ix - iy - 1;
}
}
int Healpix_Base::nest2ring (int pix) const
{
planck_assert(order_>=0, "nest2ring: need hierarchical map");
int ix, iy, face_num;
nest2xyf (pix, ix, iy, face_num);
return xyf2ring (ix, iy, face_num);
}
int Healpix_Base::ring2nest (int pix) const
{
planck_assert(order_>=0, "ring2nest: need hierarchical map");
int ix, iy, face_num;
ring2xyf (pix, ix, iy, face_num);
return xyf2nest (ix, iy, face_num);
}
int Healpix_Base::nest2peano (int pix) const
{
static const uint8 subpix[8][4] = {
{ 0, 1, 3, 2 }, { 3, 0, 2, 1 }, { 2, 3, 1, 0 }, { 1, 2, 0, 3 },
{ 0, 3, 1, 2 }, { 1, 0, 2, 3 }, { 2, 1, 3, 0 }, { 3, 2, 0, 1 } };
static const uint8 subpath[8][4] = {
{ 4, 0, 6, 0 }, { 7, 5, 1, 1 }, { 2, 4, 2, 6 }, { 3, 3, 7, 5 },
{ 0, 2, 4, 4 }, { 5, 1, 5, 3 }, { 6, 6, 0, 2 }, { 1, 7, 3, 7 } };
static const uint8 face2path[12] = {
2, 5, 2, 5, 3, 6, 3, 6, 2, 3, 2, 3 };
static const uint8 face2peanoface[12] = {
0, 5, 6, 11, 10, 1, 4, 7, 2, 3, 8, 9 };
int face = pix>>(2*order_);
uint8 path = face2path[face];
int result = 0;
for (int shift=2*order_-2; shift>=0; shift-=2)
{
uint8 spix = uint8((pix>>shift) & 0x3);
result <<= 2;
result |= subpix[path][spix];
path=subpath[path][spix];
}
return result + (int(face2peanoface[face])<<(2*order_));
}
int Healpix_Base::peano2nest (int pix) const
{
static const uint8 subpix[8][4] = {
{ 0, 1, 3, 2 }, { 1, 3, 2, 0 }, { 3, 2, 0, 1 }, { 2, 0, 1, 3 },
{ 0, 2, 3, 1 }, { 1, 0, 2, 3 }, { 3, 1, 0, 2 }, { 2, 3, 1, 0 } };
static const uint8 subpath[8][4] = {
{ 4, 0, 0, 6 }, { 5, 1, 1, 7 }, { 6, 2, 2, 4 }, { 7, 3, 3, 5 },
{ 0, 4, 4, 2 }, { 1, 5, 5, 3 }, { 2, 6, 6, 0 }, { 3, 7, 7, 1 } };
static const uint8 face2path[12] = {
2, 6, 2, 3, 3, 5, 2, 6, 2, 3, 3, 5 };
static const uint8 peanoface2face[12] = {
0, 5, 8, 9, 6, 1, 2, 7, 10, 11, 4, 3 };
int face = pix>>(2*order_);
uint8 path = face2path[face];
int result = 0;
for (int shift=2*order_-2; shift>=0; shift-=2)
{
uint8 spix = uint8((pix>>shift) & 0x3);
result <<= 2;
result |= subpix[path][spix];
path=subpath[path][spix];
}
return result + (int(peanoface2face[face])<<(2*order_));
}
int Healpix_Base::ang2pix_z_phi (double z, double phi) const
{
double za = abs(z);
double tt = fmodulo(phi,twopi) * inv_halfpi; // in [0,4)
if (scheme_==RING)
{
if (za<=twothird) // Equatorial region
{
double temp1 = nside_*(0.5+tt);
double temp2 = nside_*z*0.75;
int jp = int(temp1-temp2); // index of ascending edge line
int jm = int(temp1+temp2); // index of descending edge line
// ring number counted from z=2/3
int ir = nside_ + 1 + jp - jm; // in {1,2n+1}
int kshift = 1-(ir&1); // kshift=1 if ir even, 0 otherwise
int ip = (jp+jm-nside_+kshift+1)/2; // in {0,4n-1}
ip = imodulo(ip,4*nside_);
return ncap_ + (ir-1)*4*nside_ + ip;
}
else // North & South polar caps
{
double tp = tt-int(tt);
double tmp = nside_*sqrt(3*(1-za));
int jp = int(tp*tmp); // increasing edge line index
int jm = int((1.0-tp)*tmp); // decreasing edge line index
int ir = jp+jm+1; // ring number counted from the closest pole
int ip = int(tt*ir); // in {0,4*ir-1}
ip = imodulo(ip,4*ir);
if (z>0)
return 2*ir*(ir-1) + ip;
else
return npix_ - 2*ir*(ir+1) + ip;
}
}
else // scheme_ == NEST
{
int face_num, ix, iy;
if (za<=twothird) // Equatorial region
{
double temp1 = nside_*(0.5+tt);
double temp2 = nside_*(z*0.75);
int jp = int(temp1-temp2); // index of ascending edge line
int jm = int(temp1+temp2); // index of descending edge line
int ifp = jp >> order_; // in {0,4}
int ifm = jm >> order_;
if (ifp == ifm) // faces 4 to 7
face_num = (ifp==4) ? 4: ifp+4;
else if (ifp < ifm) // (half-)faces 0 to 3
face_num = ifp;
else // (half-)faces 8 to 11
face_num = ifm + 8;
ix = jm & (nside_-1);
iy = nside_ - (jp & (nside_-1)) - 1;
}
else // polar region, za > 2/3
{
int ntt = int(tt);
if (ntt>=4) ntt=3;
double tp = tt-ntt;
double tmp = nside_*sqrt(3*(1-za));
int jp = int(tp*tmp); // increasing edge line index
int jm = int((1.0-tp)*tmp); // decreasing edge line index
if (jp>=nside_) jp = nside_-1; // for points too close to the boundary
if (jm>=nside_) jm = nside_-1;
if (z >= 0)
{
face_num = ntt; // in {0,3}
ix = nside_ - jm - 1;
iy = nside_ - jp - 1;
}
else
{
face_num = ntt + 8; // in {8,11}
ix = jp;
iy = jm;
}
}
return xyf2nest(ix,iy,face_num);
}
}
void Healpix_Base::pix2ang_z_phi (int pix, double &z, double &phi) const
{
if (scheme_==RING)
{
if (pix<ncap_) // North Polar cap
{
int iring = int(0.5*(1+isqrt(1+2*pix))); //counted from North pole
int iphi = (pix+1) - 2*iring*(iring-1);
z = 1.0 - (iring*iring)*fact2_;
phi = (iphi-0.5) * halfpi/iring;
}
else if (pix<(npix_-ncap_)) // Equatorial region
{
int ip = pix - ncap_;
int iring = ip/(4*nside_) + nside_; // counted from North pole
int iphi = ip%(4*nside_) + 1;
// 1 if iring+nside is odd, 1/2 otherwise
double fodd = ((iring+nside_)&1) ? 1 : 0.5;
int nl2 = 2*nside_;
z = (nl2-iring)*fact1_;
phi = (iphi-fodd) * pi/nl2;
}
else // South Polar cap
{
int ip = npix_ - pix;
int iring = int(0.5*(1+isqrt(2*ip-1))); //counted from South pole
int iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
z = -1.0 + (iring*iring)*fact2_;
phi = (iphi-0.5) * halfpi/iring;
}
}
else
{
int nl4 = nside_*4;
int face_num, ix, iy;
nest2xyf(pix,ix,iy,face_num);
int jr = (jrll[face_num]<<order_) - ix - iy - 1;
int nr, kshift;
if (jr<nside_)
{
nr = jr;
z = 1 - nr*nr*fact2_;
kshift = 0;
}
else if (jr > 3*nside_)
{
nr = nl4-jr;
z = nr*nr*fact2_ - 1;
kshift = 0;
}
else
{
nr = nside_;
z = (2*nside_-jr)*fact1_;
kshift = (jr-nside_)&1;
}
int jp = (jpll[face_num]*nr + ix -iy + 1 + kshift) / 2;
if (jp>nl4) jp-=nl4;
if (jp<1) jp+=nl4;
phi = (jp-(kshift+1)*0.5)*(halfpi/nr);
}
}
void Healpix_Base::query_disc (const pointing &ptg, double radius,
vector<int>& listpix) const
{
listpix.clear();
double dth1 = fact2_;
double dth2 = fact1_;
double cosang = cos(radius);
double z0 = cos(ptg.theta);
double xa = 1./sqrt((1-z0)*(1+z0));
double rlat1 = ptg.theta - radius;
double zmax = cos(rlat1);
int irmin = ring_above (zmax)+1;
if (rlat1<=0) // north pole in the disc
for (int m=1; m<irmin; ++m) // rings completely in the disc
in_ring (m, 0, pi, listpix);
double rlat2 = ptg.theta + radius;
double zmin = cos(rlat2);
int irmax = ring_above (zmin);
// ------------- loop on ring number ---------------------
for (int iz=irmin; iz<=irmax; ++iz) // rings partially in the disc
{
double z;
if (iz<nside_) // north polar cap
z = 1.0 - iz*iz*dth1;
else if (iz <= (3*nside_)) // tropical band + equat.
z = (2*nside_-iz) * dth2;
else
z = -1.0 + (4*nside_-iz)*(4*nside_-iz)*dth1;
// --------- phi range in the disc for each z ---------
double x = (cosang-z*z0)*xa;
double ysq = 1-z*z-x*x;
planck_assert(ysq>=0, "error in query_disc()");
double dphi=atan2(sqrt(ysq),x);
in_ring (iz, ptg.phi, dphi, listpix);
}
if (rlat2>=pi) // south pole in the disc
for (int m=irmax+1; m<(4*nside_); ++m) // rings completely in the disc
in_ring (m, 0, pi, listpix);
if (scheme_==NEST)
for (tsize m=0; m<listpix.size(); ++m)
listpix[m] = ring2nest(listpix[m]);
}
void Healpix_Base::get_ring_info (int ring, int &startpix, int &ringpix,
double &costheta, double &sintheta, bool &shifted) const
{
planck_assert(scheme_==RING,"map must be in RING scheme");
int northring = (ring>2*nside_) ? 4*nside_-ring : ring;
if (northring < nside_)
{
double tmp = northring*northring*fact2_;
costheta = 1 - tmp;
sintheta = sqrt(tmp*(2-tmp));
ringpix = 4*northring;
shifted = true;
startpix = 2*northring*(northring-1);
}
else
{
costheta = (2*nside_-northring)*fact1_;
sintheta = sqrt((1+costheta)*(1-costheta));
ringpix = 4*nside_;
shifted = ((northring-nside_) & 1) == 0;
startpix = ncap_ + (northring-nside_)*ringpix;
}
if (northring != ring) // southern hemisphere
{
costheta = -costheta;
startpix = npix_ - startpix - ringpix;
}
}
void Healpix_Base::query_disc_inclusive (const pointing &dir, double radius,
vector<int> &listpix) const
{ query_disc (dir,radius+1.362*pi/(4*nside_),listpix); }
void Healpix_Base::neighbors (int pix, fix_arr<int,8> &result) const
{
static const int xoffset[] = { -1,-1, 0, 1, 1, 1, 0,-1 };
static const int yoffset[] = { 0, 1, 1, 1, 0,-1,-1,-1 };
static const int facearray[][12] =
{ { 8, 9,10,11,-1,-1,-1,-1,10,11, 8, 9 }, // S
{ 5, 6, 7, 4, 8, 9,10,11, 9,10,11, 8 }, // SE
{ -1,-1,-1,-1, 5, 6, 7, 4,-1,-1,-1,-1 }, // E
{ 4, 5, 6, 7,11, 8, 9,10,11, 8, 9,10 }, // SW
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }, // center
{ 1, 2, 3, 0, 0, 1, 2, 3, 5, 6, 7, 4 }, // NE
{ -1,-1,-1,-1, 7, 4, 5, 6,-1,-1,-1,-1 }, // W
{ 3, 0, 1, 2, 3, 0, 1, 2, 4, 5, 6, 7 }, // NW
{ 2, 3, 0, 1,-1,-1,-1,-1, 0, 1, 2, 3 } }; // N
static const int swaparray[][12] =
{ { 0,0,0,0,0,0,0,0,3,3,3,3 }, // S
{ 0,0,0,0,0,0,0,0,6,6,6,6 }, // SE
{ 0,0,0,0,0,0,0,0,0,0,0,0 }, // E
{ 0,0,0,0,0,0,0,0,5,5,5,5 }, // SW
{ 0,0,0,0,0,0,0,0,0,0,0,0 }, // center
{ 5,5,5,5,0,0,0,0,0,0,0,0 }, // NE
{ 0,0,0,0,0,0,0,0,0,0,0,0 }, // W
{ 6,6,6,6,0,0,0,0,0,0,0,0 }, // NW
{ 3,3,3,3,0,0,0,0,0,0,0,0 } }; // N
int ix, iy, face_num;
(scheme_==RING) ?
ring2xyf(pix,ix,iy,face_num) : nest2xyf(pix,ix,iy,face_num);
const int nsm1 = nside_-1;
if ((ix>0)&&(ix<nsm1)&&(iy>0)&&(iy<nsm1))
{
if (scheme_==RING)
for (int m=0; m<8; ++m)
result[m] = xyf2ring(ix+xoffset[m],iy+yoffset[m],face_num);
else
for (int m=0; m<8; ++m)
result[m] = xyf2nest(ix+xoffset[m],iy+yoffset[m],face_num);
}
else
{
for (int i=0; i<8; ++i)
{
int x=ix+xoffset[i];
int y=iy+yoffset[i];
int nbnum=4;
if (x<0)
{ x+=nside_; nbnum-=1; }
else if (x>=nside_)
{ x-=nside_; nbnum+=1; }
if (y<0)
{ y+=nside_; nbnum-=3; }
else if (y>=nside_)
{ y-=nside_; nbnum+=3; }
int f = facearray[nbnum][face_num];
if (f>=0)
{
if (swaparray[nbnum][face_num]&1) x=nside_-x-1;
if (swaparray[nbnum][face_num]&2) y=nside_-y-1;
if (swaparray[nbnum][face_num]&4) std::swap(x,y);
result[i] = (scheme_==RING) ? xyf2ring(x,y,f) : xyf2nest(x,y,f);
}
else
result[i] = -1;
}
}
}
void Healpix_Base::get_ring_info2 (int ring, int &startpix, int &ringpix,
double &theta, bool &shifted) const
{
int northring = (ring>2*nside_) ? 4*nside_-ring : ring;
if (northring < nside_)
{
double tmp = northring*northring*fact2_;
double costheta = 1 - tmp;
double sintheta = sqrt(tmp*(2-tmp));
theta = atan2(sintheta,costheta);
ringpix = 4*northring;
shifted = true;
startpix = 2*northring*(northring-1);
}
else
{
theta = acos((2*nside_-northring)*fact1_);
ringpix = 4*nside_;
shifted = ((northring-nside_) & 1) == 0;
startpix = ncap_ + (northring-nside_)*ringpix;
}
if (northring != ring) // southern hemisphere
{
theta = pi-theta;
startpix = npix_ - startpix - ringpix;
}
}
void Healpix_Base::get_interpol (const pointing &ptg, fix_arr<int,4> &pix,
fix_arr<double,4> &wgt) const
{
double z = cos (ptg.theta);
int ir1 = ring_above(z);
int ir2 = ir1+1;
double theta1, theta2, w1, tmp, dphi;
int sp,nr;
bool shift;
int i1,i2;
if (ir1>0)
{
get_ring_info2 (ir1, sp, nr, theta1, shift);
dphi = twopi/nr;
tmp = (ptg.phi/dphi - .5*shift);
i1 = (tmp<0) ? int(tmp)-1 : int(tmp);
w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
i2 = i1+1;
if (i1<0) i1 +=nr;
if (i2>=nr) i2 -=nr;
pix[0] = sp+i1; pix[1] = sp+i2;
wgt[0] = 1-w1; wgt[1] = w1;
}
if (ir2<(4*nside_))
{
get_ring_info2 (ir2, sp, nr, theta2, shift);
dphi = twopi/nr;
tmp = (ptg.phi/dphi - .5*shift);
i1 = (tmp<0) ? int(tmp)-1 : int(tmp);
w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
i2 = i1+1;
if (i1<0) i1 +=nr;
if (i2>=nr) i2 -=nr;
pix[2] = sp+i1; pix[3] = sp+i2;
wgt[2] = 1-w1; wgt[3] = w1;
}
if (ir1==0)
{
double wtheta = ptg.theta/theta2;
wgt[2] *= wtheta; wgt[3] *= wtheta;
double fac = (1-wtheta)*0.25;
wgt[0] = fac; wgt[1] = fac; wgt[2] += fac; wgt[3] +=fac;
pix[0] = (pix[2]+2)%4;
pix[1] = (pix[3]+2)%4;
}
else if (ir2==4*nside_)
{
double wtheta = (ptg.theta-theta1)/(pi-theta1);
wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
double fac = wtheta*0.25;
wgt[0] += fac; wgt[1] += fac; wgt[2] = fac; wgt[3] =fac;
pix[2] = ((pix[0]+2)&3)+npix_-4;
pix[3] = ((pix[1]+2)&3)+npix_-4;
}
else
{
double wtheta = (ptg.theta-theta1)/(theta2-theta1);
wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
wgt[2] *= wtheta; wgt[3] *= wtheta;
}
if (scheme_==NEST)
for (tsize m=0; m<pix.size(); ++m)
pix[m] = ring2nest(pix[m]);
}
double Healpix_Base::max_pixrad() const
{
vec3 va,vb;
va.set_z_phi (2./3., pi/(4*nside_));
double t1 = 1.-1./nside_;
t1*=t1;
vb.set_z_phi (1-t1/3, 0);
return v_angle(va,vb);
}

View file

@ -0,0 +1,283 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file healpix_base.h
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef HEALPIX_BASE_H
#define HEALPIX_BASE_H
#include <vector>
#include "cxxutils.h"
#include "pointing.h"
#include "arr.h"
/*! The two possible ordering schemes of a HEALPix map. */
enum Healpix_Ordering_Scheme { RING, /*!< RING scheme */
NEST /*!< NESTED scheme */
};
Healpix_Ordering_Scheme string2HealpixScheme (const std::string &inp);
class nside_dummy {};
extern const nside_dummy SET_NSIDE;
/*! Functionality related to the HEALPix pixelisation. */
class Healpix_Base
{
protected:
enum { order_max=13 };
class Tablefiller
{
public:
Tablefiller();
};
static Tablefiller Filler;
friend class Tablefiller;
static short ctab[0x100], utab[0x100];
static const int jrll[];
static const int jpll[];
/*! The order of the map; -1 for nonhierarchical map. */
int order_;
/*! The N_side parameter of the map; 0 if not allocated. */
int nside_;
int npface_, ncap_, npix_;
double fact1_, fact2_;
/*! The map's ordering scheme. */
Healpix_Ordering_Scheme scheme_;
inline int ring_above (double z) const;
void in_ring (int iz, double phi0, double dphi,
std::vector<int> &listir) const;
int xyf2nest(int ix, int iy, int face_num) const;
void nest2xyf(int pix, int &ix, int &iy, int &face_num) const;
int xyf2ring(int ix, int iy, int face_num) const;
void ring2xyf(int pix, int &ix, int &iy, int &face_num) const;
typedef int (Healpix_Base::*swapfunc)(int pix) const;
typedef void (Healpix_Base::*pix2xyf)
(int pix, int &x, int &y, int &f) const;
typedef int (Healpix_Base::*xyf2pix) (int x, int y, int f) const;
public:
/*! Calculates the map order from its \a N_side parameter.
Returns -1 if \a nside is not a power of 2.
\param nside the \a N_side parameter */
static int nside2order (int nside)
{
planck_assert (nside>0, "invalid value for Nside");
if ((nside)&(nside-1)) return -1;
return ilog2(nside);
}
/*! Calculates the \a N_side parameter from the number of pixels.
\param npix the number of pixels */
static int npix2nside (int npix);
/*! Constructs an unallocated object. */
Healpix_Base ()
: order_(-1), nside_(0), npface_(0), ncap_(0), npix_(0),
fact1_(0), fact2_(0), scheme_(RING) {}
/*! Constructs an object with a given \a order and the ordering
scheme \a scheme. */
Healpix_Base (int order, Healpix_Ordering_Scheme scheme)
{ Set (order, scheme); }
/*! Constructs an object with a given \a nside and the ordering
scheme \a scheme. The \a nside_dummy parameter must be set to
SET_NSIDE. */
Healpix_Base (int nside, Healpix_Ordering_Scheme scheme, const nside_dummy)
{ SetNside (nside, scheme); }
/* Adjusts the object to \a order and \a scheme. */
void Set (int order, Healpix_Ordering_Scheme scheme)
{
planck_assert ((order>=0)&&(order<=order_max), "bad order");
order_ = order;
nside_ = 1<<order;
npface_ = nside_<<order_;
ncap_ = (npface_-nside_)<<1;
npix_ = 12*npface_;
fact2_ = 4./npix_;
fact1_ = (nside_<<1)*fact2_;
scheme_ = scheme;
}
/* Adjusts the object to \a nside and \a scheme. */
void SetNside (int nside, Healpix_Ordering_Scheme scheme)
{
order_ = nside2order(nside);
planck_assert ((scheme!=NEST) || (order_>=0),
"SetNside: nside must be power of 2 for nested maps");
nside_ = nside;
npface_ = nside_*nside_;
ncap_ = (npface_-nside_)<<1;
npix_ = 12*npface_;
fact2_ = 4./npix_;
fact1_ = (nside_<<1)*fact2_;
scheme_ = scheme;
}
/*! Returns the z-coordinate of the ring \a ring. This also works
for the (not really existing) rings 0 and 4*nside. */
double ring2z (int ring) const;
/*! Returns the number of the ring in which \a pix lies. */
int pix2ring (int pix) const;
/*! Translates a pixel number from NEST to RING. */
int nest2ring (int pix) const;
/*! Translates a pixel number from RING to NEST. */
int ring2nest (int pix) const;
/*! Translates a pixel number from NEST to its Peano index. */
int nest2peano (int pix) const;
/*! Translates a pixel number from its Peano index to NEST. */
int peano2nest (int pix) const;
int ang2pix_z_phi (double z, double phi) const;
/*! Returns the number of the pixel which contains the angular coordinates
\a ang. */
int ang2pix (const pointing &ang) const
{ return ang2pix_z_phi (cos(ang.theta), ang.phi); }
/*! Returns the number of the pixel which contains the vector \a vec
(\a vec is normalized if necessary). */
int vec2pix (const vec3 &vec) const
{ return ang2pix_z_phi (vec.z/vec.Length(), safe_atan2(vec.y,vec.x)); }
void pix2ang_z_phi (int pix, double &z, double &phi) const;
/*! Returns the angular coordinates of the center of the pixel with
number \a pix. */
pointing pix2ang (int pix) const
{
double z, phi;
pix2ang_z_phi (pix,z,phi);
return pointing(acos(z),phi);
}
/*! Returns the vector to the center of the pixel with number \a pix. */
vec3 pix2vec (int pix) const
{
double z, phi;
pix2ang_z_phi (pix,z,phi);
vec3 res;
res.set_z_phi (z, phi);
return res;
}
/*! Returns the numbers of all pixels whose centers lie within \a radius
of \a dir in \a listpix.
\param dir the angular coordinates of the disc center
\param radius the radius (in radians) of the disc
\param listpix a vector containing the numbers of all pixels within
the disc
\note This method is more efficient in the RING scheme. */
void query_disc (const pointing &dir, double radius,
std::vector<int> &listpix) const;
/*! Returns the numbers of all pixels that lie at least partially within
\a radius of \a dir in \a listpix. It may also return a few pixels
which do not lie in the disk at all.
\param dir the angular coordinates of the disc center
\param radius the radius (in radians) of the disc
\param listpix a vector containing the numbers of all pixels within
the disc
\note This method works in both RING and NEST schemes, but is
considerably faster in the RING scheme. */
void query_disc_inclusive (const pointing &dir, double radius,
std::vector<int> &listpix) const;
/*! Returns useful information about a given ring of the map.
\param ring the ring number (the number of the first ring is 1)
\param startpix the number of the first pixel in the ring
\param ringpix the number of pixels in the ring
\param costheta the cosine of the colatitude of the ring
\param sintheta the sine of the colatitude of the ring
\param shifted if \a true, the center of the first pixel is not at
\a phi=0 */
void get_ring_info (int ring, int &startpix, int &ringpix,
double &costheta, double &sintheta, bool &shifted) const;
/*! Returns useful information about a given ring of the map.
\param ring the ring number (the number of the first ring is 1)
\param startpix the number of the first pixel in the ring
\param ringpix the number of pixels in the ring
\param theta the colatitude (in radians) of the ring
\param shifted if \a true, the center of the first pixel is not at
\a phi=0 */
void get_ring_info2 (int ring, int &startpix, int &ringpix,
double &theta, bool &shifted) const;
/*! Returns the neighboring pixels of \a pix in \a result.
On exit, \a result contains (in this order)
the pixel numbers of the SW, W, NW, N, NE, E, SE and S neighbor
of \a pix. If a neighbor does not exist (this can only be the case
for the W, N, E and S neighbors), its entry is set to -1.
\note This method works in both RING and NEST schemes, but is
considerably faster in the NEST scheme. */
void neighbors (int pix, fix_arr<int,8> &result) const;
/*! Returns interpolation information for the direction \a ptg.
The surrounding pixels are returned in \a pix, their corresponding
weights in \a wgt.
\note This method works in both RING and NEST schemes, but is
considerably faster in the RING scheme. */
void get_interpol (const pointing &ptg, fix_arr<int,4> &pix,
fix_arr<double,4> &wgt) const;
/*! Returns the order parameter of the object. */
int Order() const { return order_; }
/*! Returns the \a N_side parameter of the object. */
int Nside() const { return nside_; }
/*! Returns the number of pixels of the object. */
int Npix() const { return npix_; }
/*! Returns the ordering scheme of the object. */
Healpix_Ordering_Scheme Scheme() const { return scheme_; }
/*! Returns \a true, if both objects have the same nside and scheme,
else \a false. */
bool conformable (const Healpix_Base &other) const
{ return ((nside_==other.nside_) && (scheme_==other.scheme_)); }
/*! Swaps the contents of two Healpix_Base objects. */
void swap (Healpix_Base &other)
{
std::swap(order_,other.order_);
std::swap(nside_,other.nside_);
std::swap(npface_,other.npface_);
std::swap(ncap_,other.ncap_);
std::swap(npix_,other.npix_);
std::swap(fact1_,other.fact1_);
std::swap(fact2_,other.fact2_);
std::swap(scheme_,other.scheme_);
}
/*! Returns the maximum angular distance (in radian) between any pixel
center and its corners. */
double max_pixrad() const;
};
#endif

View file

@ -0,0 +1,707 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "healpix_base2.h"
#include "cxxutils.h"
#include "pointing.h"
#include "arr.h"
#include "geom_utils.h"
#include "lsconstants.h"
using namespace std;
short Healpix_Base2::ctab[];
short Healpix_Base2::utab[];
Healpix_Base2::Tablefiller::Tablefiller()
{
for (int m=0; m<0x100; ++m)
{
ctab[m] = short(
(m&0x1 ) | ((m&0x2 ) << 7) | ((m&0x4 ) >> 1) | ((m&0x8 ) << 6)
| ((m&0x10) >> 2) | ((m&0x20) << 5) | ((m&0x40) >> 3) | ((m&0x80) << 4));
utab[m] = short(
(m&0x1 ) | ((m&0x2 ) << 1) | ((m&0x4 ) << 2) | ((m&0x8 ) << 3)
| ((m&0x10) << 4) | ((m&0x20) << 5) | ((m&0x40) << 6) | ((m&0x80) << 7));
}
}
Healpix_Base2::Tablefiller Healpix_Base2::Filler;
const int Healpix_Base2::jrll[] = { 2,2,2,2,3,3,3,3,4,4,4,4 };
const int Healpix_Base2::jpll[] = { 1,3,5,7,0,2,4,6,1,3,5,7 };
int64 Healpix_Base2::npix2nside (int64 npix)
{
int64 res=isqrt(npix/12);
planck_assert (npix==res*res*12, "npix2nside: invalid argument");
return res;
}
int64 Healpix_Base2::ring_above (double z) const
{
double az=abs(z);
if (az>twothird) // polar caps
{
int64 iring = int64(nside_*sqrt(3*(1-az)));
return (z>0) ? iring : 4*nside_-iring-1;
}
else // ----- equatorial region ---------
return int64(nside_*(2-1.5*z));
}
void Healpix_Base2::nest2xyf (int64 pix, int &ix, int &iy, int &face_num)
const
{
face_num = int(pix>>(2*order_));
pix &= (npface_-1);
int32 raw = ((pix&0x555500000000ull)>>16)
| ((pix&0x5555000000000000ull)>>31)
| (pix&0x5555)
| ((pix&0x55550000)>>15);
ix = ctab[raw&0xff]
| (ctab[(raw>>8)&0xff]<<4)
| (ctab[(raw>>16)&0xff]<<16)
| (ctab[(raw>>24)&0xff]<<20);
pix >>= 1;
raw = ((pix&0x555500000000ull)>>16)
| ((pix&0x5555000000000000ull)>>31)
| (pix&0x5555)
| ((pix&0x55550000)>>15);
iy = ctab[raw&0xff]
| (ctab[(raw>>8)&0xff]<<4)
| (ctab[(raw>>16)&0xff]<<16)
| (ctab[(raw>>24)&0xff]<<20);
}
int64 Healpix_Base2::xyf2nest (int ix, int iy, int face_num) const
{
return (int64(face_num)<<(2*order_)) +
( (int64(utab[ ix &0xff]))
| (int64(utab[(ix>> 8)&0xff])<<16)
| (int64(utab[(ix>>16)&0xff])<<32)
| (int64(utab[(ix>>24)&0xff])<<48)
| (int64(utab[ iy &0xff])<<1)
| (int64(utab[(iy>> 8)&0xff])<<17)
| (int64(utab[(iy>>16)&0xff])<<33)
| (int64(utab[(iy>>24)&0xff])<<49) );
}
void Healpix_Base2::ring2xyf (int64 pix, int &ix, int &iy, int &face_num)
const
{
int64 iring, iphi, kshift, nr;
int64 nl2 = 2*nside_;
if (pix<ncap_) // North Polar cap
{
iring = int64(0.5*(1+isqrt(1+2*pix))); //counted from North pole
iphi = (pix+1) - 2*iring*(iring-1);
kshift = 0;
nr = iring;
face_num=0;
int64 tmp = iphi-1;
if (tmp>=(2*iring))
{
face_num=2;
tmp-=2*iring;
}
if (tmp>=iring) ++face_num;
}
else if (pix<(npix_-ncap_)) // Equatorial region
{
int64 ip = pix - ncap_;
if (order_>=0)
{
iring = (ip>>(order_+2)) + nside_; // counted from North pole
iphi = (ip&(4*nside_-1)) + 1;
}
else
{
iring = (ip/(4*nside_)) + nside_; // counted from North pole
iphi = (ip%(4*nside_)) + 1;
}
kshift = (iring+nside_)&1;
nr = nside_;
int64 ire = iring-nside_+1;
int64 irm = nl2+2-ire;
int64 ifm, ifp;
if (order_>=0)
{
ifm = (iphi - ire/2 + nside_ -1) >> order_;
ifp = (iphi - irm/2 + nside_ -1) >> order_;
}
else
{
ifm = (iphi - ire/2 + nside_ -1) / nside_;
ifp = (iphi - irm/2 + nside_ -1) / nside_;
}
if (ifp == ifm) // faces 4 to 7
face_num = (ifp==4) ? 4 : ifp+4;
else if (ifp<ifm) // (half-)faces 0 to 3
face_num = ifp;
else // (half-)faces 8 to 11
face_num = ifm + 8;
}
else // South Polar cap
{
int64 ip = npix_ - pix;
iring = int64(0.5*(1+isqrt(2*ip-1))); //counted from South pole
iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
kshift = 0;
nr = iring;
iring = 2*nl2-iring;
face_num=8;
int64 tmp = iphi-1;
if (tmp>=(2*nr))
{
face_num=10;
tmp-=2*nr;
}
if (tmp>=nr) ++face_num;
}
int64 irt = iring - (jrll[face_num]*nside_) + 1;
int64 ipt = 2*iphi- jpll[face_num]*nr - kshift -1;
if (ipt>=nl2) ipt-=8*nside_;
ix = (ipt-irt) >>1;
iy =(-(ipt+irt))>>1;
}
int64 Healpix_Base2::xyf2ring (int ix, int iy, int face_num) const
{
int64 nl4 = 4*nside_;
int64 jr = (jrll[face_num]*nside_) - ix - iy - 1;
int64 nr, kshift, n_before;
if (jr<nside_)
{
nr = jr;
n_before = 2*nr*(nr-1);
kshift = 0;
}
else if (jr > 3*nside_)
{
nr = nl4-jr;
n_before = npix_ - 2*(nr+1)*nr;
kshift = 0;
}
else
{
nr = nside_;
n_before = ncap_ + (jr-nside_)*nl4;
kshift = (jr-nside_)&1;
}
int64 jp = (jpll[face_num]*nr + ix - iy + 1 + kshift) / 2;
if (jp>nl4)
jp-=nl4;
else
if (jp<1) jp+=nl4;
return n_before + jp - 1;
}
double Healpix_Base2::ring2z (int64 ring) const
{
if (ring<nside_)
return 1 - ring*ring*fact2_;
if (ring <=3*nside_)
return (2*nside_-ring)*fact1_;
ring=4*nside_ - ring;
return ring*ring*fact2_ - 1;
}
int64 Healpix_Base2::pix2ring (int64 pix) const
{
if (scheme_==RING)
{
if (pix<ncap_) // North Polar cap
return int64(0.5*(1+isqrt(1+2*pix))); //counted from North pole
else if (pix<(npix_-ncap_)) // Equatorial region
{
int64 ip = pix - ncap_;
return ip/(4*nside_) + nside_; // counted from North pole
}
else // South Polar cap
{
int64 ip = npix_ - pix;
return 4*nside_ - int64(0.5*(1+isqrt(2*ip-1))); //counted from South pole
}
}
else
{
int face_num, ix, iy;
nest2xyf(pix,ix,iy,face_num);
return (int64(jrll[face_num])<<order_) - ix - iy - 1;
}
}
int64 Healpix_Base2::nest2ring (int64 pix) const
{
planck_assert(order_>=0, "nest2ring: need hierarchical map");
int ix, iy, face_num;
nest2xyf (pix, ix, iy, face_num);
return xyf2ring (ix, iy, face_num);
}
int64 Healpix_Base2::ring2nest (int64 pix) const
{
planck_assert(order_>=0, "ring2nest: need hierarchical map");
int ix, iy, face_num;
ring2xyf (pix, ix, iy, face_num);
return xyf2nest (ix, iy, face_num);
}
int64 Healpix_Base2::nest2peano (int64 pix) const
{
static const uint8 subpix[8][4] = {
{ 0, 1, 3, 2 }, { 3, 0, 2, 1 }, { 2, 3, 1, 0 }, { 1, 2, 0, 3 },
{ 0, 3, 1, 2 }, { 1, 0, 2, 3 }, { 2, 1, 3, 0 }, { 3, 2, 0, 1 } };
static const uint8 subpath[8][4] = {
{ 4, 0, 6, 0 }, { 7, 5, 1, 1 }, { 2, 4, 2, 6 }, { 3, 3, 7, 5 },
{ 0, 2, 4, 4 }, { 5, 1, 5, 3 }, { 6, 6, 0, 2 }, { 1, 7, 3, 7 } };
static const uint8 face2path[12] = {
2, 5, 2, 5, 3, 6, 3, 6, 2, 3, 2, 3 };
static const uint8 face2peanoface[12] = {
0, 5, 6, 11, 10, 1, 4, 7, 2, 3, 8, 9 };
int face = pix>>(2*order_);
uint8 path = face2path[face];
int64 result = 0;
for (int shift=2*order_-2; shift>=0; shift-=2)
{
uint8 spix = uint8((pix>>shift) & 0x3);
result <<= 2;
result |= subpix[path][spix];
path=subpath[path][spix];
}
return result + (int64(face2peanoface[face])<<(2*order_));
}
int64 Healpix_Base2::peano2nest (int64 pix) const
{
static const uint8 subpix[8][4] = {
{ 0, 1, 3, 2 }, { 1, 3, 2, 0 }, { 3, 2, 0, 1 }, { 2, 0, 1, 3 },
{ 0, 2, 3, 1 }, { 1, 0, 2, 3 }, { 3, 1, 0, 2 }, { 2, 3, 1, 0 } };
static const uint8 subpath[8][4] = {
{ 4, 0, 0, 6 }, { 5, 1, 1, 7 }, { 6, 2, 2, 4 }, { 7, 3, 3, 5 },
{ 0, 4, 4, 2 }, { 1, 5, 5, 3 }, { 2, 6, 6, 0 }, { 3, 7, 7, 1 } };
static const uint8 face2path[12] = {
2, 6, 2, 3, 3, 5, 2, 6, 2, 3, 3, 5 };
static const uint8 peanoface2face[12] = {
0, 5, 8, 9, 6, 1, 2, 7, 10, 11, 4, 3 };
int face = pix>>(2*order_);
uint8 path = face2path[face];
int64 result = 0;
for (int shift=2*order_-2; shift>=0; shift-=2)
{
uint8 spix = uint8((pix>>shift) & 0x3);
result <<= 2;
result |= subpix[path][spix];
path=subpath[path][spix];
}
return result + (int64(peanoface2face[face])<<(2*order_));
}
int64 Healpix_Base2::ang2pix_z_phi (double z, double phi) const
{
double za = abs(z);
double tt = fmodulo(phi,twopi) * inv_halfpi; // in [0,4)
if (scheme_==RING)
{
if (za<=twothird) // Equatorial region
{
double temp1 = nside_*(0.5+tt);
double temp2 = nside_*z*0.75;
int64 jp = int64(temp1-temp2); // index of ascending edge line
int64 jm = int64(temp1+temp2); // index of descending edge line
// ring number counted from z=2/3
int64 ir = nside_ + 1 + jp - jm; // in {1,2n+1}
int kshift = 1-(ir&1); // kshift=1 if ir even, 0 otherwise
int64 ip = (jp+jm-nside_+kshift+1)/2; // in {0,4n-1}
ip = imodulo<int64>(ip,4*nside_);
return ncap_ + (ir-1)*4*nside_ + ip;
}
else // North & South polar caps
{
double tp = tt-int(tt);
double tmp = nside_*sqrt(3*(1-za));
int64 jp = int64(tp*tmp); // increasing edge line index
int64 jm = int64((1.0-tp)*tmp); // decreasing edge line index
int64 ir = jp+jm+1; // ring number counted from the closest pole
int64 ip = int64(tt*ir); // in {0,4*ir-1}
ip = imodulo<int64>(ip,4*ir);
if (z>0)
return 2*ir*(ir-1) + ip;
else
return npix_ - 2*ir*(ir+1) + ip;
}
}
else // scheme_ == NEST
{
int face_num, ix, iy;
if (za<=twothird) // Equatorial region
{
double temp1 = nside_*(0.5+tt);
double temp2 = nside_*(z*0.75);
int64 jp = int64(temp1-temp2); // index of ascending edge line
int64 jm = int64(temp1+temp2); // index of descending edge line
int64 ifp = jp >> order_; // in {0,4}
int64 ifm = jm >> order_;
if (ifp == ifm) // faces 4 to 7
face_num = (ifp==4) ? 4: ifp+4;
else if (ifp < ifm) // (half-)faces 0 to 3
face_num = ifp;
else // (half-)faces 8 to 11
face_num = ifm + 8;
ix = jm & (nside_-1);
iy = nside_ - (jp & (nside_-1)) - 1;
}
else // polar region, za > 2/3
{
int ntt = int(tt);
if (ntt>=4) ntt=3;
double tp = tt-ntt;
double tmp = nside_*sqrt(3*(1-za));
int64 jp = int64(tp*tmp); // increasing edge line index
int64 jm = int64((1.0-tp)*tmp); // decreasing edge line index
if (jp>=nside_) jp = nside_-1; // for points too close to the boundary
if (jm>=nside_) jm = nside_-1;
if (z >= 0)
{
face_num = ntt; // in {0,3}
ix = nside_ - jm - 1;
iy = nside_ - jp - 1;
}
else
{
face_num = ntt + 8; // in {8,11}
ix = jp;
iy = jm;
}
}
return xyf2nest(ix,iy,face_num);
}
}
void Healpix_Base2::pix2ang_z_phi (int64 pix, double &z, double &phi) const
{
if (scheme_==RING)
{
if (pix<ncap_) // North Polar cap
{
int64 iring = int64(0.5*(1+isqrt(1+2*pix))); //counted from North pole
int64 iphi = (pix+1) - 2*iring*(iring-1);
z = 1.0 - (iring*iring)*fact2_;
phi = (iphi-0.5) * halfpi/iring;
}
else if (pix<(npix_-ncap_)) // Equatorial region
{
int64 ip = pix - ncap_;
int64 iring = ip/(4*nside_) + nside_; // counted from North pole
int64 iphi = ip%(4*nside_) + 1;
// 1 if iring+nside is odd, 1/2 otherwise
double fodd = ((iring+nside_)&1) ? 1 : 0.5;
int64 nl2 = 2*nside_;
z = (nl2-iring)*fact1_;
phi = (iphi-fodd) * pi/nl2;
}
else // South Polar cap
{
int64 ip = npix_ - pix;
int64 iring = int64(0.5*(1+isqrt(2*ip-1))); //counted from South pole
int64 iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
z = -1.0 + (iring*iring)*fact2_;
phi = (iphi-0.5) * halfpi/iring;
}
}
else
{
int64 nl4 = nside_*4;
int face_num, ix, iy;
nest2xyf(pix,ix,iy,face_num);
int64 jr = (int64(jrll[face_num])<<order_) - ix - iy - 1;
int64 nr;
int kshift;
if (jr<nside_)
{
nr = jr;
z = 1 - nr*nr*fact2_;
kshift = 0;
}
else if (jr > 3*nside_)
{
nr = nl4-jr;
z = nr*nr*fact2_ - 1;
kshift = 0;
}
else
{
nr = nside_;
z = (2*nside_-jr)*fact1_;
kshift = (jr-nside_)&1;
}
int64 jp = (jpll[face_num]*nr + ix -iy + 1 + kshift) / 2;
if (jp>nl4) jp-=nl4;
if (jp<1) jp+=nl4;
phi = (jp-(kshift+1)*0.5)*(halfpi/nr);
}
}
void Healpix_Base2::get_ring_info (int64 ring, int64 &startpix, int64 &ringpix,
double &costheta, double &sintheta, bool &shifted) const
{
planck_assert(scheme_==RING,"map must be in RING scheme");
int64 northring = (ring>2*nside_) ? 4*nside_-ring : ring;
if (northring < nside_)
{
double tmp = northring*northring*fact2_;
costheta = 1 - tmp;
sintheta = sqrt(tmp*(2-tmp));
ringpix = 4*northring;
shifted = true;
startpix = 2*northring*(northring-1);
}
else
{
costheta = (2*nside_-northring)*fact1_;
sintheta = sqrt((1+costheta)*(1-costheta));
ringpix = 4*nside_;
shifted = ((northring-nside_) & 1) == 0;
startpix = ncap_ + (northring-nside_)*ringpix;
}
if (northring != ring) // southern hemisphere
{
costheta = -costheta;
startpix = npix_ - startpix - ringpix;
}
}
void Healpix_Base2::neighbors (int64 pix, fix_arr<int64,8> &result) const
{
static const int xoffset[] = { -1,-1, 0, 1, 1, 1, 0,-1 };
static const int yoffset[] = { 0, 1, 1, 1, 0,-1,-1,-1 };
static const int facearray[][12] =
{ { 8, 9,10,11,-1,-1,-1,-1,10,11, 8, 9 }, // S
{ 5, 6, 7, 4, 8, 9,10,11, 9,10,11, 8 }, // SE
{ -1,-1,-1,-1, 5, 6, 7, 4,-1,-1,-1,-1 }, // E
{ 4, 5, 6, 7,11, 8, 9,10,11, 8, 9,10 }, // SW
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }, // center
{ 1, 2, 3, 0, 0, 1, 2, 3, 5, 6, 7, 4 }, // NE
{ -1,-1,-1,-1, 7, 4, 5, 6,-1,-1,-1,-1 }, // W
{ 3, 0, 1, 2, 3, 0, 1, 2, 4, 5, 6, 7 }, // NW
{ 2, 3, 0, 1,-1,-1,-1,-1, 0, 1, 2, 3 } }; // N
static const int swaparray[][12] =
{ { 0,0,0,0,0,0,0,0,3,3,3,3 }, // S
{ 0,0,0,0,0,0,0,0,6,6,6,6 }, // SE
{ 0,0,0,0,0,0,0,0,0,0,0,0 }, // E
{ 0,0,0,0,0,0,0,0,5,5,5,5 }, // SW
{ 0,0,0,0,0,0,0,0,0,0,0,0 }, // center
{ 5,5,5,5,0,0,0,0,0,0,0,0 }, // NE
{ 0,0,0,0,0,0,0,0,0,0,0,0 }, // W
{ 6,6,6,6,0,0,0,0,0,0,0,0 }, // NW
{ 3,3,3,3,0,0,0,0,0,0,0,0 } }; // N
int ix, iy, face_num;
(scheme_==RING) ?
ring2xyf(pix,ix,iy,face_num) : nest2xyf(pix,ix,iy,face_num);
const int64 nsm1 = nside_-1;
if ((ix>0)&&(ix<nsm1)&&(iy>0)&&(iy<nsm1))
{
if (scheme_==RING)
for (int m=0; m<8; ++m)
result[m] = xyf2ring(ix+xoffset[m],iy+yoffset[m],face_num);
else
for (int m=0; m<8; ++m)
result[m] = xyf2nest(ix+xoffset[m],iy+yoffset[m],face_num);
}
else
{
for (int i=0; i<8; ++i)
{
int x=ix+xoffset[i];
int y=iy+yoffset[i];
int nbnum=4;
if (x<0)
{ x+=nside_; nbnum-=1; }
else if (x>=nside_)
{ x-=nside_; nbnum+=1; }
if (y<0)
{ y+=nside_; nbnum-=3; }
else if (y>=nside_)
{ y-=nside_; nbnum+=3; }
int f = facearray[nbnum][face_num];
if (f>=0)
{
if (swaparray[nbnum][face_num]&1) x=nside_-x-1;
if (swaparray[nbnum][face_num]&2) y=nside_-y-1;
if (swaparray[nbnum][face_num]&4) std::swap(x,y);
result[i] = (scheme_==RING) ? xyf2ring(x,y,f) : xyf2nest(x,y,f);
}
else
result[i] = -1;
}
}
}
void Healpix_Base2::get_ring_info2 (int64 ring, int64 &startpix, int64 &ringpix,
double &theta, bool &shifted) const
{
int64 northring = (ring>2*nside_) ? 4*nside_-ring : ring;
if (northring < nside_)
{
double tmp = northring*northring*fact2_;
double costheta = 1 - tmp;
double sintheta = sqrt(tmp*(2-tmp));
theta = atan2(sintheta,costheta);
ringpix = 4*northring;
shifted = true;
startpix = 2*northring*(northring-1);
}
else
{
theta = acos((2*nside_-northring)*fact1_);
ringpix = 4*nside_;
shifted = ((northring-nside_) & 1) == 0;
startpix = ncap_ + (northring-nside_)*ringpix;
}
if (northring != ring) // southern hemisphere
{
theta = pi-theta;
startpix = npix_ - startpix - ringpix;
}
}
void Healpix_Base2::get_interpol (const pointing &ptg, fix_arr<int64,4> &pix,
fix_arr<double,4> &wgt) const
{
double z = cos (ptg.theta);
int64 ir1 = ring_above(z);
int64 ir2 = ir1+1;
double theta1, theta2, w1, tmp, dphi;
int64 sp,nr;
bool shift;
int64 i1,i2;
if (ir1>0)
{
get_ring_info2 (ir1, sp, nr, theta1, shift);
dphi = twopi/nr;
tmp = (ptg.phi/dphi - .5*shift);
i1 = (tmp<0) ? int64(tmp)-1 : int64(tmp);
w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
i2 = i1+1;
if (i1<0) i1 +=nr;
if (i2>=nr) i2 -=nr;
pix[0] = sp+i1; pix[1] = sp+i2;
wgt[0] = 1-w1; wgt[1] = w1;
}
if (ir2<(4*nside_))
{
get_ring_info2 (ir2, sp, nr, theta2, shift);
dphi = twopi/nr;
tmp = (ptg.phi/dphi - .5*shift);
i1 = (tmp<0) ? int64(tmp)-1 : int64(tmp);
w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
i2 = i1+1;
if (i1<0) i1 +=nr;
if (i2>=nr) i2 -=nr;
pix[2] = sp+i1; pix[3] = sp+i2;
wgt[2] = 1-w1; wgt[3] = w1;
}
if (ir1==0)
{
double wtheta = ptg.theta/theta2;
wgt[2] *= wtheta; wgt[3] *= wtheta;
double fac = (1-wtheta)*0.25;
wgt[0] = fac; wgt[1] = fac; wgt[2] += fac; wgt[3] +=fac;
pix[0] = (pix[2]+2)%4;
pix[1] = (pix[3]+2)%4;
}
else if (ir2==4*nside_)
{
double wtheta = (ptg.theta-theta1)/(pi-theta1);
wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
double fac = wtheta*0.25;
wgt[0] += fac; wgt[1] += fac; wgt[2] = fac; wgt[3] =fac;
pix[2] = ((pix[0]+2)&3)+npix_-4;
pix[3] = ((pix[1]+2)&3)+npix_-4;
}
else
{
double wtheta = (ptg.theta-theta1)/(theta2-theta1);
wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
wgt[2] *= wtheta; wgt[3] *= wtheta;
}
if (scheme_==NEST)
for (tsize m=0; m<pix.size(); ++m)
pix[m] = ring2nest(pix[m]);
}
double Healpix_Base2::max_pixrad() const
{
vec3 va,vb;
va.set_z_phi (2./3., pi/(4*nside_));
double t1 = 1.-1./nside_;
t1*=t1;
vb.set_z_phi (1-t1/3, 0);
return v_angle(va,vb);
}

View file

@ -0,0 +1,250 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file healpix_base2.h
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef HEALPIX_BASE2_H
#define HEALPIX_BASE2_H
#include "healpix_base.h"
#include "datatypes.h"
/*! Functionality related to the HEALPix pixelisation. Supports resolutions up to
N_side = 2^29. */
class Healpix_Base2
{
protected:
enum { order_max=29 };
class Tablefiller
{
public:
Tablefiller();
};
static Tablefiller Filler;
friend class Tablefiller;
static short ctab[0x100], utab[0x100];
static const int jrll[];
static const int jpll[];
/*! The order of the map; -1 for nonhierarchical map. */
int order_;
/*! The N_side parameter of the map; 0 if not allocated. */
int64 nside_;
int64 npface_, ncap_, npix_;
double fact1_, fact2_;
/*! The map's ordering scheme. */
Healpix_Ordering_Scheme scheme_;
inline int64 ring_above (double z) const;
int64 xyf2nest(int ix, int iy, int face_num) const;
void nest2xyf(int64 pix, int &ix, int &iy, int &face_num) const;
int64 xyf2ring(int ix, int iy, int face_num) const;
void ring2xyf(int64 pix, int &ix, int &iy, int &face_num) const;
typedef int64 (Healpix_Base2::*swapfunc)(int64 pix) const;
typedef void (Healpix_Base2::*pix2xyf)
(int64 pix, int &x, int &y, int &f) const;
typedef int64 (Healpix_Base2::*xyf2pix) (int x, int y, int f) const;
public:
/*! Calculates the map order from its \a N_side parameter.
Returns -1 if \a nside is not a power of 2.
\param nside the \a N_side parameter */
static int nside2order (int64 nside)
{
planck_assert (nside>0, "invalid value for Nside");
if ((nside)&(nside-1)) return -1;
return ilog2(nside);
}
/*! Calculates the \a N_side parameter from the number of pixels.
\param npix the number of pixels */
static int64 npix2nside (int64 npix);
/*! Constructs an unallocated object. */
Healpix_Base2 ()
: order_(-1), nside_(0), npface_(0), ncap_(0), npix_(0),
fact1_(0), fact2_(0), scheme_(RING) {}
/*! Constructs an object with a given \a order and the ordering
scheme \a scheme. */
Healpix_Base2 (int order, Healpix_Ordering_Scheme scheme)
{ Set (order, scheme); }
/*! Constructs an object with a given \a nside and the ordering
scheme \a scheme. The \a nside_dummy parameter must be set to
SET_NSIDE. */
Healpix_Base2 (int64 nside, Healpix_Ordering_Scheme scheme,
const nside_dummy)
{ SetNside (nside, scheme); }
/* Adjusts the object to \a order and \a scheme. */
void Set (int order, Healpix_Ordering_Scheme scheme)
{
planck_assert ((order>=0)&&(order<=order_max), "bad order");
order_ = order;
nside_ = int64(1)<<order;
npface_ = nside_<<order_;
ncap_ = (npface_-nside_)<<1;
npix_ = 12*npface_;
fact2_ = 4./npix_;
fact1_ = (nside_<<1)*fact2_;
scheme_ = scheme;
}
/* Adjusts the object to \a nside and \a scheme. */
void SetNside (int64 nside, Healpix_Ordering_Scheme scheme)
{
order_ = nside2order(nside);
planck_assert ((scheme!=NEST) || (order_>=0),
"SetNside: nside must be power of 2 for nested maps");
nside_ = nside;
npface_ = nside_*nside_;
ncap_ = (npface_-nside_)<<1;
npix_ = 12*npface_;
fact2_ = 4./npix_;
fact1_ = (nside_<<1)*fact2_;
scheme_ = scheme;
}
/*! Returns the z-coordinate of the ring \a ring. This also works
for the (not really existing) rings 0 and 4*nside. */
double ring2z (int64 ring) const;
/*! Returns the number of the ring in which \a pix lies. */
int64 pix2ring (int64 pix) const;
/*! Translates a pixel number from NEST to RING. */
int64 nest2ring (int64 pix) const;
/*! Translates a pixel number from RING to NEST. */
int64 ring2nest (int64 pix) const;
/*! Translates a pixel number from NEST to its Peano index. */
int64 nest2peano (int64 pix) const;
/*! Translates a pixel number from its Peano index to NEST. */
int64 peano2nest (int64 pix) const;
int64 ang2pix_z_phi (double z, double phi) const;
/*! Returns the number of the pixel which contains the angular coordinates
\a ang. */
int64 ang2pix (const pointing &ang) const
{ return ang2pix_z_phi (cos(ang.theta), ang.phi); }
/*! Returns the number of the pixel which contains the vector \a vec
(\a vec is normalized if necessary). */
int64 vec2pix (const vec3 &vec) const
{ return ang2pix_z_phi (vec.z/vec.Length(), safe_atan2(vec.y,vec.x)); }
void pix2ang_z_phi (int64 pix, double &z, double &phi) const;
/*! Returns the angular coordinates of the center of the pixel with
number \a pix. */
pointing pix2ang (int64 pix) const
{
double z, phi;
pix2ang_z_phi (pix,z,phi);
return pointing(acos(z),phi);
}
/*! Returns the vector to the center of the pixel with number \a pix. */
vec3 pix2vec (int64 pix) const
{
double z, phi;
pix2ang_z_phi (pix,z,phi);
vec3 res;
res.set_z_phi (z, phi);
return res;
}
/*! Returns useful information about a given ring of the map.
\param ring the ring number (the number of the first ring is 1)
\param startpix the number of the first pixel in the ring
\param ringpix the number of pixels in the ring
\param costheta the cosine of the colatitude of the ring
\param sintheta the sine of the colatitude of the ring
\param shifted if \a true, the center of the first pixel is not at
\a phi=0 */
void get_ring_info (int64 ring, int64 &startpix, int64 &ringpix,
double &costheta, double &sintheta, bool &shifted) const;
/*! Returns useful information about a given ring of the map.
\param ring the ring number (the number of the first ring is 1)
\param startpix the number of the first pixel in the ring
\param ringpix the number of pixels in the ring
\param theta the colatitude (in radians) of the ring
\param shifted if \a true, the center of the first pixel is not at
\a phi=0 */
void get_ring_info2 (int64 ring, int64 &startpix, int64 &ringpix,
double &theta, bool &shifted) const;
/*! Returns the neighboring pixels of \a pix in \a result.
On exit, \a result contains (in this order)
the pixel numbers of the SW, W, NW, N, NE, E, SE and S neighbor
of \a pix. If a neighbor does not exist (this can only be the case
for the W, N, E and S neighbors), its entry is set to -1.
\note This method works in both RING and NEST schemes, but is
considerably faster in the NEST scheme. */
void neighbors (int64 pix, fix_arr<int64,8> &result) const;
/*! Returns interpolation information for the direction \a ptg.
The surrounding pixels are returned in \a pix, their corresponding
weights in \a wgt.
\note This method works in both RING and NEST schemes, but is
considerably faster in the RING scheme. */
void get_interpol (const pointing &ptg, fix_arr<int64,4> &pix,
fix_arr<double,4> &wgt) const;
/*! Returns the order parameter of the object. */
int Order() const { return order_; }
/*! Returns the \a N_side parameter of the object. */
int64 Nside() const { return nside_; }
/*! Returns the number of pixels of the object. */
int64 Npix() const { return npix_; }
/*! Returns the ordering scheme of the object. */
Healpix_Ordering_Scheme Scheme() const { return scheme_; }
/*! Returns \a true, if both objects have the same nside and scheme,
else \a false. */
bool conformable (const Healpix_Base2 &other) const
{ return ((nside_==other.nside_) && (scheme_==other.scheme_)); }
/*! Swaps the contents of two Healpix_Base objects. */
void swap (Healpix_Base2 &other)
{
std::swap(order_,other.order_);
std::swap(nside_,other.nside_);
std::swap(npface_,other.npface_);
std::swap(ncap_,other.ncap_);
std::swap(npix_,other.npix_);
std::swap(fact1_,other.fact1_);
std::swap(fact2_,other.fact2_);
std::swap(scheme_,other.scheme_);
}
/*! Returns the maximum angular distance (in radian) between any pixel
center and its corners. */
double max_pixrad() const;
};
#endif

View file

@ -0,0 +1,112 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003, 2005, 2009 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "healpix_data_io.h"
#include "arr.h"
#include "fitshandle.h"
#include "paramfile.h"
using namespace std;
void read_weight_ring (const string &dir, int nside, arr<double> &weight)
{
fitshandle inp;
inp.open(dir+"/weight_ring_n"+intToString(nside,5)+".fits");
inp.goto_hdu(2);
weight.alloc (2*nside);
inp.read_column(1,weight);
}
void get_ring_weights (paramfile &params, int nside, arr<double> &weight)
{
bool weighted = params.find<bool>("weighted",false);
weight.alloc (2*nside);
if (weighted)
{
string datadir = params.find<string>("healpix_data");
read_weight_ring (datadir, nside, weight);
for (tsize m=0; m<weight.size(); ++m) weight[m]+=1;
}
else
weight.fill(1);
}
void read_pixwin (const string &dir, int nside, arr<double> &temp)
{
fitshandle inp;
inp.open(dir+"/pixel_window_n"+intToString(nside,4)+".fits");
inp.goto_hdu(2);
if (temp.size()==0)
inp.read_entire_column(1,temp);
else
inp.read_column(1,temp);
}
void read_pixwin (const string &dir, int nside, arr<double> &temp,
arr<double> &pol)
{
fitshandle inp;
inp.open(dir+"/pixel_window_n"+intToString(nside,4)+".fits");
inp.goto_hdu(2);
if (temp.size()==0)
inp.read_entire_column(1,temp);
else
inp.read_column(1,temp);
if (pol.size()==0)
inp.read_entire_column(2,pol);
else
inp.read_column(2,pol);
}
void get_pixwin (paramfile &params, int lmax, int nside, arr<double> &pixwin)
{
bool do_pixwin = params.find<bool>("pixel_window",false);
pixwin.alloc(lmax+1);
pixwin.fill(1);
if (do_pixwin)
{
string datadir = params.find<string>("healpix_data");
read_pixwin (datadir,nside,pixwin);
}
}
void get_pixwin (paramfile &params, int lmax, int nside, arr<double> &pixwin,
arr<double> &pixwin_pol)
{
bool do_pixwin = params.find<bool>("pixel_window",false);
pixwin.alloc(lmax+1);
pixwin.fill(1);
pixwin_pol.alloc(lmax+1);
pixwin_pol.fill(1);
if (do_pixwin)
{
string datadir = params.find<string>("healpix_data");
read_pixwin (datadir,nside,pixwin,pixwin_pol);
}
}

View file

@ -0,0 +1,51 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003, 2005 Max-Planck-Society
* Author: Martin Reinecke
*/
#ifndef HEALPIX_DATA_IO_H
#define HEALPIX_DATA_IO_H
#include <string>
class paramfile;
template<typename T> class arr;
void read_weight_ring (const std::string &dir, int nside, arr<double> &weight);
void get_ring_weights (paramfile &params, int nside, arr<double> &weight);
void read_pixwin (const std::string &dir, int nside, arr<double> &temp);
void read_pixwin (const std::string &dir, int nside, arr<double> &temp,
arr<double> &pol);
void get_pixwin (paramfile &params, int lmax, int nside, arr<double> &pixwin);
void get_pixwin (paramfile &params, int lmax, int nside, arr<double> &pixwin,
arr<double> &pixwin_pol);
#endif

View file

@ -0,0 +1,94 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "healpix_map.h"
using namespace std;
template<typename T> void Healpix_Map<T>::Import_degrade
(const Healpix_Map<T> &orig, bool pessimistic)
{
planck_assert(nside_<orig.nside_,"Import_degrade: this is no degrade");
int fact = orig.nside_/nside_;
planck_assert (orig.nside_==nside_*fact,
"the larger Nside must be a multiple of the smaller one");
pix2xyf to_xyf = (scheme_==RING) ?
&Healpix_Map::ring2xyf : &Healpix_Map::nest2xyf;
xyf2pix from_xyf = (orig.scheme_==RING) ?
&Healpix_Map::xyf2ring : &Healpix_Map::xyf2nest;
int minhits = pessimistic ? fact : 1;
#pragma omp parallel
{
int m;
#pragma omp for schedule (static)
for (m=0; m<npix_; ++m)
{
int x,y,f;
(this->*to_xyf)(m,x,y,f);
int hits = 0;
double sum = 0;
for (int j=fact*y; j<fact*(y+1); ++j)
for (int i=fact*x; i<fact*(x+1); ++i)
{
int opix = (orig.*from_xyf)(i,j,f);
if (!approx<double>(orig.map[opix],Healpix_undef))
{
++hits;
sum += orig.map[opix];
}
}
map[m] = T((hits<minhits) ? Healpix_undef : sum/hits);
}
}
}
template void Healpix_Map<float>::Import_degrade
(const Healpix_Map<float> &orig, bool pessimistic);
template void Healpix_Map<double>::Import_degrade
(const Healpix_Map<double> &orig, bool pessimistic);
template<typename T> void Healpix_Map<T>::minmax (T &Min, T &Max) const
{
Min = T(1e30); Max = T(-1e30);
for (int m=0; m<npix_; ++m)
{
T val = map[m];
if (!approx<double>(val,Healpix_undef))
{
if (val>Max) Max=val;
if (val<Min) Min=val;
}
}
}
template void Healpix_Map<float>::minmax (float &Min, float &Max) const;
template void Healpix_Map<double>::minmax (double &Min, double &Max) const;

View file

@ -0,0 +1,316 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file healpix_map.h
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef HEALPIX_MAP_H
#define HEALPIX_MAP_H
#include "arr.h"
#include "healpix_base.h"
//! Healpix value representing "undefined"
const double Healpix_undef=-1.6375e30;
/*! A HEALPix map of a given datatype */
template<typename T> class Healpix_Map: public Healpix_Base
{
private:
arr<T> map;
public:
/*! Constructs an unallocated map. */
Healpix_Map () {}
/*! Constructs a map with a given \a order and the ordering
scheme \a scheme. */
Healpix_Map (int order, Healpix_Ordering_Scheme scheme)
: Healpix_Base (order, scheme), map(npix_) {}
/*! Constructs a map with a given \a nside and the ordering
scheme \a scheme. */
Healpix_Map (int nside, Healpix_Ordering_Scheme scheme, const nside_dummy)
: Healpix_Base (nside, scheme, SET_NSIDE), map(npix_) {}
/*! Constructs a map from the contents of \a data and sets the ordering
scheme to \a Scheme. The size of \a data must be a valid HEALPix
map size. */
Healpix_Map (const arr<T> &data, Healpix_Ordering_Scheme scheme)
: Healpix_Base (npix2nside(data.size()), scheme, SET_NSIDE), map(data) {}
/*! Deletes the old map, creates a map from the contents of \a data and
sets the ordering scheme to \a scheme. The size of \a data must be a
valid HEALPix map size.
\note On exit, \a data is zero-sized! */
void Set (arr<T> &data, Healpix_Ordering_Scheme scheme)
{
Healpix_Base::SetNside(npix2nside (data.size()), scheme);
map.transfer(data);
}
/*! Deletes the old map and creates a new map with a given \a order
and the ordering scheme \a scheme. */
void Set (int order, Healpix_Ordering_Scheme scheme)
{
Healpix_Base::Set(order, scheme);
map.alloc(npix_);
}
/*! Deletes the old map and creates a new map with a given \a nside
and the ordering scheme \a scheme. */
void SetNside (int nside, Healpix_Ordering_Scheme scheme)
{
Healpix_Base::SetNside(nside, scheme);
map.alloc(npix_);
}
/*! Fills the map with \a val. */
void fill (const T &val)
{ map.fill(val); }
/*! Imports the map \a orig into the current map, adjusting the
ordering scheme. \a orig must have the same resolution as the
current map. */
void Import_nograde (const Healpix_Map<T> &orig)
{
planck_assert (nside_==orig.nside_,
"Import_nograde: maps have different nside");
if (orig.scheme_ == scheme_)
for (int m=0; m<npix_; ++m) map[m] = orig.map[m];
else
{
swapfunc swapper = (scheme_ == NEST) ?
&Healpix_Base::ring2nest : &Healpix_Base::nest2ring;
#pragma omp parallel
{
int m;
#pragma omp for schedule (dynamic,5000)
for (m=0; m<npix_; ++m) map[(this->*swapper)(m)] = orig.map[m];
}
}
}
/*! Imports the map \a orig into the current map, adjusting the
ordering scheme and the map resolution. \a orig must have higher
resolution than the current map. */
void Import_upgrade (const Healpix_Map<T> &orig)
{
planck_assert(nside_>orig.nside_,"Import_upgrade: this is no upgrade");
int fact = nside_/orig.nside_;
planck_assert (nside_==orig.nside_*fact,
"the larger Nside must be a multiple of the smaller one");
pix2xyf to_xyf = (orig.scheme_==RING) ?
&Healpix_Map::ring2xyf : &Healpix_Map::nest2xyf;
xyf2pix from_xyf = (scheme_==RING) ?
&Healpix_Map::xyf2ring : &Healpix_Map::xyf2nest;
#pragma omp parallel
{
int m;
#pragma omp for schedule (dynamic,5000)
for (m=0; m<orig.npix_; ++m)
{
int x,y,f;
(orig.*to_xyf)(m,x,y,f);
for (int j=fact*y; j<fact*(y+1); ++j)
for (int i=fact*x; i<fact*(x+1); ++i)
{
int mypix = (this->*from_xyf)(i,j,f);
map[mypix] = orig.map[m];
}
}
}
}
/*! Imports the map \a orig into the current map, adjusting the
ordering scheme and the map resolution. \a orig must have higher
resolution than the current map.
\a pessimistic determines whether or not
pixels are set to \a Healpix_undef when not all of the corresponding
high-resolution pixels are defined.
This method is instantiated for \a float and \a double only. */
void Import_degrade (const Healpix_Map<T> &orig, bool pessimistic=false);
/*! Imports the map \a orig into the current map, adjusting the
ordering scheme and the map resolution if necessary.
When downgrading, \a pessimistic determines whether or not
pixels are set to \a Healpix_undef when not all of the corresponding
high-resolution pixels are defined.
This method is instantiated for \a float and \a double only. */
void Import (const Healpix_Map<T> &orig, bool pessimistic=false)
{
if (orig.nside_ == nside_) // no up/degrading
Import_nograde(orig);
else if (orig.nside_ < nside_) // upgrading
Import_upgrade(orig);
else
Import_degrade(orig,pessimistic);
}
/*! Returns a constant reference to the pixel with the number \a pix. */
const T &operator[] (int pix) const { return map[pix]; }
/*! Returns a reference to the pixel with the number \a pix. */
T &operator[] (int pix) { return map[pix]; }
/*! Swaps the map ordering from RING to NEST and vice versa.
This is done in-place (i.e. with negligible space overhead). */
void swap_scheme()
{
static const int clen[] = { 0,7,5,4,12,10,13,18,14,19,18,17,27,21 };
static const int cycle[][30] = {
{ },
{ 0,1,8,12,16,21,40 },
{ 0,1,2,40,114 },
{ 0,4,160,263 },
{ 0,4,30,49,51,87,526,1027,1105,1387,1807,2637 },
{ 0,8,10,18,39,74,146,307,452,4737 },
{ 0,1,2,7,9,17,80,410,1526,1921,32859,33566,38931 },
{ 0,5,6,10,12,24,27,95,372,494,924,1409,3492,4248,9137,66043,103369,
156899 },
{ 0,1,2,3,4,45,125,351,697,24337,102940,266194,341855,419857 },
{ 0,1,2,3,9,16,1705,2082,2126,8177,12753,15410,52642,80493,83235,
88387,99444,1675361,2495125 },
{ 0,2,6,8,9,11,20,50,93,152,183,2137,13671,44794,486954,741908,
4803258,5692573 },
{ 0,1,5,6,44,53,470,2847,3433,4906,13654,14710,400447,1797382,
2744492,18775974,23541521 },
{ 0,4,9,10,16,33,83,117,318,451,5759,10015,128975,171834,211256,
347608,1278690,2154097,2590798,3427694,5581717,21012301,27023976,
72522811,95032729,139166747,171822389 },
{ 0,5,10,267,344,363,2968,3159,9083,18437,76602,147614,1246902,
1593138,2035574,6529391,9511830,11340287,29565945,281666026,
677946848 } };
swapfunc swapper = (scheme_ == NEST) ?
&Healpix_Base::ring2nest : &Healpix_Base::nest2ring;
planck_assert (order_>=0, "swap_scheme(): need hierarchical map");
for (int m=0; m<clen[order_]; ++m)
{
int istart = cycle[order_][m];
T pixbuf = map[istart];
int iold = istart, inew = (this->*swapper)(istart);
while (inew != istart)
{
map[iold] = map[inew];
iold = inew;
inew = (this->*swapper)(inew);
}
map[iold] = pixbuf;
}
scheme_ = (scheme_==RING) ? NEST : RING;
}
/*! performs the actual interpolation using \a pix and \a wgt. */
T interpolation (const fix_arr<int,4> &pix,
const fix_arr<double,4> &wgt) const
{
return T(map[pix[0]]*wgt[0] + map[pix[1]]*wgt[1]
+ map[pix[2]]*wgt[2] + map[pix[3]]*wgt[3]);
}
/*! Returns the interpolated map value at \a ptg */
T interpolated_value (const pointing &ptg) const
{
fix_arr<int,4> pix;
fix_arr<double,4> wgt;
get_interpol (ptg, pix, wgt);
return interpolation (pix, wgt);
}
/*! Returns a constant reference to the map data. */
const arr<T> &Map() const { return map; }
/*! Returns the minimum and maximum value of the map in
\a Min and \a Max.
This method is instantiated for \a float and \a double only. */
void minmax (T &Min, T &Max) const;
/*! Swaps the contents of two Healpix_Map objects. */
void swap (Healpix_Map &other)
{
Healpix_Base::swap(other);
map.swap(other.map);
}
/*! Returns the average of all defined map pixels. */
double average() const
{
double avg=0;
int pix=0;
for (int m=0; m<npix_; ++m)
if (!approx<double>(map[m],Healpix_undef))
{ ++pix; avg+=map[m]; }
return avg/pix;
}
/*! Adds \a val to all defined map pixels. */
void Add (T val)
{
for (int m=0; m<npix_; ++m)
if (!approx<double>(map[m],Healpix_undef))
{ map[m]+=val; }
}
/*! Multiplies all defined map pixels by \a val. */
void Scale (T val)
{
for (int m=0; m<npix_; ++m)
if (!approx<double>(map[m],Healpix_undef))
{ map[m]*=val; }
}
/*! Returns the root mean square of the map, not counting undefined
pixels. */
double rms() const
{
using namespace std;
double result=0;
int pix=0;
for (int m=0; m<npix_; ++m)
if (!approx<double>(map[m],Healpix_undef))
{ ++pix; result+=map[m]*map[m]; }
return sqrt(result/pix);
}
/*! Returns the maximum absolute value in the map, ignoring undefined
pixels. */
T absmax() const
{
using namespace std;
T result=0;
for (int m=0; m<npix_; ++m)
if (!approx<double>(map[m],Healpix_undef))
{ result = max(result,abs(map[m])); }
return result;
}
};
#endif

View file

@ -0,0 +1,144 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "healpix_map_fitsio.h"
#include "healpix_map.h"
#include "fitshandle.h"
using namespace std;
namespace {
unsigned int healpix_repcount (tsize npix)
{
if (npix<1024) return 1;
if ((npix%1024)==0) return 1024;
return isqrt (npix/12);
}
} // unnamed namespace
template<typename T> void read_Healpix_map_from_fits
(fitshandle &inp, Healpix_Map<T> &map, int colnum)
{
arr<T> myarr;
inp.read_entire_column (colnum, myarr);
int64 nside = inp.get_key<int>("NSIDE");
planck_assert (int64(myarr.size())==12*nside*nside,
string("mismatch between number of map pixels ("
+dataToString(myarr.size())+") and Nside ("+dataToString(nside)+")"));
map.Set (myarr, string2HealpixScheme(inp.get_key<string>("ORDERING")));
}
template void read_Healpix_map_from_fits (fitshandle &inp,
Healpix_Map<float> &map, int colnum);
template void read_Healpix_map_from_fits (fitshandle &inp,
Healpix_Map<double> &map, int colnum);
template void read_Healpix_map_from_fits (fitshandle &inp,
Healpix_Map<int> &map, int colnum);
template<typename T> void read_Healpix_map_from_fits
(const string &filename, Healpix_Map<T> &map, int colnum, int hdunum)
{
fitshandle inp;
inp.open (filename);
inp.goto_hdu (hdunum);
read_Healpix_map_from_fits (inp,map,colnum);
}
template void read_Healpix_map_from_fits (const string &filename,
Healpix_Map<float> &map, int colnum, int hdunum);
template void read_Healpix_map_from_fits (const string &filename,
Healpix_Map<double> &map, int colnum, int hdunum);
template void read_Healpix_map_from_fits (const string &filename,
Healpix_Map<int> &map, int colnum, int hdunum);
void prepare_Healpix_fitsmap
(fitshandle &out, const Healpix_Base &base, PDT datatype,
const arr<string> &colname)
{
vector<fitscolumn> cols;
int repcount = healpix_repcount (base.Npix());
for (tsize m=0; m<colname.size(); ++m)
cols.push_back (fitscolumn (colname[m],"unknown",repcount, datatype));
out.insert_bintab(cols);
out.set_key ("PIXTYPE",string("HEALPIX"),"HEALPIX pixelisation");
string ordering = (base.Scheme()==RING) ? "RING" : "NESTED";
out.set_key ("ORDERING",ordering,
"Pixel ordering scheme, either RING or NESTED");
out.set_key ("NSIDE",base.Nside(),"Resolution parameter for HEALPIX");
out.set_key ("FIRSTPIX",0,"First pixel # (0 based)");
out.set_key ("LASTPIX",base.Npix()-1,"Last pixel # (0 based)");
out.set_key ("INDXSCHM",string("IMPLICIT"),
"Indexing: IMPLICIT or EXPLICIT");
}
template<typename T> void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<T> &map, PDT datatype)
{
arr<string> colname(1);
colname[0] = "signal";
prepare_Healpix_fitsmap (out, map, datatype, colname);
out.write_column(1,map.Map());
}
template void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<float> &map, PDT datatype);
template void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<double> &map, PDT datatype);
template void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<int> &map, PDT datatype);
template<typename T> void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ, const Healpix_Map<T> &mapU, PDT datatype)
{
arr<string> colname(3);
colname[0] = "signal";
colname[1] = "Q-pol";
colname[2] = "U-pol";
prepare_Healpix_fitsmap (out, mapT, datatype, colname);
out.write_column(1,mapT.Map());
out.write_column(2,mapQ.Map());
out.write_column(3,mapU.Map());
}
template void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<float> &mapT,
const Healpix_Map<float> &mapQ, const Healpix_Map<float> &mapU,
PDT datatype);
template void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<double> &mapT,
const Healpix_Map<double> &mapQ, const Healpix_Map<double> &mapU,
PDT datatype);

View file

@ -0,0 +1,111 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file healpix_map_fitsio.h
* Copyright (C) 2003-2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef HEALPIX_MAP_FITSIO_H
#define HEALPIX_MAP_FITSIO_H
#include <string>
#include "datatypes.h"
#include "fitshandle.h"
class Healpix_Base;
template<typename T> class arr;
template<typename T> class Healpix_Map;
/*! \defgroup healpix_map_fitsio_group FITS-based I/O of HEALPix maps */
/*! \{ */
/*! Reads the map stored in column \a colnum of the FITS binary table
pointed to by \a inp into \a map. */
template<typename T> void read_Healpix_map_from_fits
(fitshandle &inp, Healpix_Map<T> &map, int colnum=1);
/*! Opens the FITS file \a filename, jumps to the HDU \a hdunum,
and reads the column \a colnum into \a map. */
template<typename T> void read_Healpix_map_from_fits
(const std::string &filename, Healpix_Map<T> &map, int colnum=1,
int hdunum=2);
template<typename T> inline void read_Healpix_map_from_fits
(const std::string &filename, Healpix_Map<T> &mapT, Healpix_Map<T> &mapQ,
Healpix_Map<T> &mapU, int hdunum=2)
{
fitshandle inp;
inp.open(filename);
inp.goto_hdu(hdunum);
read_Healpix_map_from_fits(inp,mapT,1);
read_Healpix_map_from_fits(inp,mapQ,2);
read_Healpix_map_from_fits(inp,mapU,3);
}
/*! Inserts a new binary table into \a out, which contains one column
of Planck type \a datatype with the name \a name, and writes all HEALPix
specific keywords based on the information in \a base. */
void prepare_Healpix_fitsmap
(fitshandle &out, const Healpix_Base &base, PDT datatype,
const arr<std::string> &colname);
/*! Inserts a new binary table into \a out, which contains one column
of Planck type \a datatype, and stores \a map into this column. */
template<typename T> void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<T> &map, PDT datatype);
/*! Inserts a new binary table into \a out, which contains three columns
of Planck type \a datatype, and stores \a mapT, \a mapQ and \a mapU
into these columns. */
template<typename T> void write_Healpix_map_to_fits
(fitshandle &out, const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ, const Healpix_Map<T> &mapU, PDT datatype);
/*! Creates a new FITS file with the name \a outfile, with a binary table in
HDU 2, which contains one column of Planck type \a datatype, and stores
\a map into this column. */
template<typename T> inline void write_Healpix_map_to_fits
(const std::string &outfile, const Healpix_Map<T> &map, PDT datatype)
{
fitshandle out;
out.create (outfile);
write_Healpix_map_to_fits (out,map,datatype);
}
/*! Creates a new FITS file with the name \a outfile, with a binary table in
HDU 2, which contains three columns of Planck type \a datatype, and stores
\a mapT, \a mapQ and \a mapU into this column. */
template<typename T> inline void write_Healpix_map_to_fits
(const std::string &outfile, const Healpix_Map<T> &mapT,
const Healpix_Map<T> &mapQ, const Healpix_Map<T> &mapU, PDT datatype)
{
fitshandle out;
out.create (outfile);
write_Healpix_map_to_fits (out,mapT,mapQ,mapU,datatype);
}
/*! \} */
#endif

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
hotspots_cxx_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,97 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include <fstream>
#include "cxxutils.h"
#include "paramfile.h"
#include "healpix_map.h"
#include "healpix_map_fitsio.h"
#include "fitshandle.h"
#include "levels_facilities.h"
using namespace std;
int hotspots_cxx_module (int argc, const char **argv)
{
module_startup ("hotspots_cxx", argc, argv, 2, "<parameter file>");
paramfile params (argv[1]);
string infile = params.find<string>("infile");
string mapfile = params.find<string>("outmap","");
bool have_mapfile = mapfile!="";
string minfile = params.find<string>("minfile","");
bool have_minfile = minfile!="";
string maxfile = params.find<string>("maxfile","");
bool have_maxfile = maxfile!="";
planck_assert (have_mapfile || have_minfile || have_maxfile,
"no output file specified");
Healpix_Map<float> inmap;
read_Healpix_map_from_fits(infile,inmap,1,2);
Healpix_Map<float> outmap;
if (have_mapfile) outmap.Set(inmap.Order(),inmap.Scheme());
ofstream minout, maxout;
if (have_minfile) minout.open(minfile.c_str());
if (have_maxfile) maxout.open(maxfile.c_str());
fix_arr<int,8> nb;
// FIXME: This should be parallelized
for (int m=0; m<inmap.Npix(); ++m)
{
float value = inmap[m];
if (!approx<double>(value, Healpix_undef))
{
inmap.neighbors(m,nb);
bool ismax=true, ismin=true;
for (tsize n=0; n<nb.size(); ++n)
{
if (nb[n] >=0)
{
float nbval = inmap[nb[n]];
if (!approx<double>(nbval, Healpix_undef))
{
if (nbval>=value) ismax=false;
if (nbval<=value) ismin=false;
}
}
}
if (have_mapfile)
outmap[m] = float((ismax||ismin) ? value : Healpix_undef);
if (have_minfile && ismin) minout << m << " " << value << endl;
if (have_maxfile && ismax) maxout << m << " " << value << endl;
}
}
if (have_mapfile)
write_Healpix_map_to_fits (mapfile,outmap,PLANCK_FLOAT32);
return 0;
}

709
external/healpix/Healpix_cxx/hpxtest.cc vendored Normal file
View file

@ -0,0 +1,709 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Max-Planck-Society
* Author: Martin Reinecke
*/
/*
Candidates for testing the validity of the Healpix routines:
- done: ang2pix(pix2ang(i)) = i for all Healpix_Bases
- done: pix2ang(ang2pix(ptg)) dot ptg > 1-delta for all Healpix_Bases
- done: ring2nest(nest2ring(i)) = i for all hierarchical Healpix_Bases
- done: downgrade(upgrade(map)) = map for all maps
- done: map and downgraded map should have same average
- done: alm2map(map2alm(map)) approx map (same for pol)
- partly done: neighbor tests
- powspec -> alm -> powspec (should produce similar powspecs, also for pol)
- done: two swap_schemes() should produce original map
- done: query_disc tests (dot products etc.)
- a_lms: test Set(), Scale(), Add(), alm(l,m) = alm.mstart(m)[l], etc.
*/
#include <iostream>
#include "healpix_base.h"
#include "healpix_base2.h"
#include "healpix_map.h"
#include "arr.h"
#include "planck_rng.h"
#include "lsconstants.h"
#include "alm.h"
#include "alm_healpix_tools.h"
#include "alm_powspec_tools.h"
#include "geom_utils.h"
using namespace std;
const int nsamples = 1000000;
planck_rng rng;
namespace {
void random_dir (pointing &ptg)
{
ptg.theta = acos(rng.rand_uni()*2-1);
ptg.phi = rng.rand_uni()*twopi;
}
void check_ringnestring()
{
cout << "testing ring2nest(nest2ring(m))==m" << endl;
for (int order=0; order<=13; ++order)
{
cout << "order = " << order << endl;
Healpix_Base base (order,RING);
for (int m=0; m<nsamples; ++m)
{
int pix = int(rng.rand_uni()*base.Npix());
if (base.ring2nest(base.nest2ring(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
}
void check_ringnestring2()
{
cout << "testing ring2nest(nest2ring(m))==m" << endl;
for (int order=0; order<=29; ++order)
{
cout << "order = " << order << endl;
Healpix_Base2 base (order,RING);
for (int m=0; m<nsamples; ++m)
{
int64 pix = int64(rng.rand_uni()*base.Npix());
if (base.ring2nest(base.nest2ring(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
}
void check_nestpeanonest()
{
cout << "testing peano2nest(nest2peano(m))==m" << endl;
for (int order=0; order<=13; ++order)
{
cout << "order = " << order << endl;
Healpix_Base base (order,NEST);
for (int m=0; m<nsamples; ++m)
{
int pix = int(rng.rand_uni()*base.Npix());
if (base.peano2nest(base.nest2peano(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
}
void check_nestpeanonest2()
{
cout << "testing peano2nest(nest2peano(m))==m" << endl;
for (int order=0; order<=29; ++order)
{
cout << "order = " << order << endl;
Healpix_Base2 base (order,NEST);
for (int m=0; m<nsamples; ++m)
{
int64 pix = int64(rng.rand_uni()*base.Npix());
if (base.peano2nest(base.nest2peano(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
}
void check_pixangpix()
{
cout << "testing ang2pix(pix2ang(m))==m" << endl;
for (int order=0; order<=13; ++order)
{
cout << "order = " << order << endl;
Healpix_Base base1 (order,RING);
Healpix_Base base2 (order,NEST);
for (int m=0; m<nsamples; ++m)
{
int pix = int(rng.rand_uni()*base1.Npix());
if (base1.ang2pix(base1.pix2ang(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
if (base2.ang2pix(base2.pix2ang(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
for (int nside=3; nside<(1<<13); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base base (nside,RING,SET_NSIDE);
for (int m=0; m<nsamples; ++m)
{
int pix = int(rng.rand_uni()*base.Npix());
if (base.ang2pix(base.pix2ang(pix))!=pix)
cout << " PROBLEM: nside = " << nside << ", pixel = " << pix << endl;
}
}
}
void check_pixangpix2()
{
cout << "testing ang2pix(pix2ang(m))==m" << endl;
for (int order=0; order<=29; ++order)
{
cout << "order = " << order << endl;
Healpix_Base2 base1 (order,RING);
Healpix_Base2 base2 (order,NEST);
for (int m=0; m<nsamples; ++m)
{
int64 pix = int64(rng.rand_uni()*base1.Npix());
if (base1.ang2pix(base1.pix2ang(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
if (base2.ang2pix(base2.pix2ang(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
for (int nside=3; nside<(1<<29); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base2 base (nside,RING,SET_NSIDE);
for (int m=0; m<nsamples; ++m)
{
int64 pix = int64(rng.rand_uni()*base.Npix());
if (base.ang2pix(base.pix2ang(pix))!=pix)
cout << " PROBLEM: nside = " << nside << ", pixel = " << pix << endl;
}
}
}
void check_pixvecpix()
{
cout << "testing vec2pix(pix2vec(m))==m" << endl;
for (int order=0; order<=13; ++order)
{
cout << "order = " << order << endl;
Healpix_Base base1 (order,RING);
Healpix_Base base2 (order,NEST);
for (int m=0; m<nsamples; ++m)
{
int pix = int(rng.rand_uni()*base1.Npix());
if (base1.vec2pix(base1.pix2vec(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
if (base2.vec2pix(base2.pix2vec(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
for (int nside=3; nside<(1<<13); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base base (nside,RING,SET_NSIDE);
for (int m=0; m<nsamples; ++m)
{
int pix = int(rng.rand_uni()*base.Npix());
if (base.vec2pix(base.pix2vec(pix))!=pix)
cout << " PROBLEM: nside = " << nside << ", pixel = " << pix << endl;
}
}
}
void check_pixvecpix2()
{
cout << "testing vec2pix(pix2vec(m))==m" << endl;
for (int order=0; order<=29; ++order)
{
cout << "order = " << order << endl;
Healpix_Base2 base1 (order,RING);
Healpix_Base2 base2 (order,NEST);
for (int m=0; m<nsamples; ++m)
{
int64 pix = int64(rng.rand_uni()*base1.Npix());
if (base1.vec2pix(base1.pix2vec(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
if (base2.vec2pix(base2.pix2vec(pix))!=pix)
cout << " PROBLEM: order = " << order << ", pixel = " << pix << endl;
}
}
for (int nside=3; nside<(1<<29); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base2 base (nside,RING,SET_NSIDE);
for (int m=0; m<nsamples; ++m)
{
int64 pix = int64(rng.rand_uni()*base.Npix());
if (base.vec2pix(base.pix2vec(pix))!=pix)
cout << " PROBLEM: nside = " << nside << ", pixel = " << pix << endl;
}
}
}
void check_angpixang()
{
cout << "testing pix2ang(ang2pix(ptg)) approx ptg" << endl;
for (int order=0; order<=13; ++order)
{
cout << "order = " << order << endl;
Healpix_Base base1 (order,NEST);
Healpix_Base base2 (order,RING);
double maxang = base1.max_pixrad();
for (int m=0; m<nsamples; ++m)
{
pointing ptg;
random_dir (ptg);
if (v_angle(base1.pix2ang(base1.ang2pix(ptg)),ptg)>maxang)
cout << " PROBLEM: order = " << order << ", ptg = " << ptg << endl;
if (v_angle(base2.pix2ang(base2.ang2pix(ptg)),ptg)>maxang)
cout << " PROBLEM: order = " << order << ", ptg = " << ptg << endl;
}
}
for (int nside=3; nside<(1<<13); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base base (nside,RING,SET_NSIDE);
double maxang = base.max_pixrad();
for (int m=0; m<nsamples; ++m)
{
pointing ptg;
random_dir (ptg);
if (v_angle(base.pix2ang(base.ang2pix(ptg)),ptg)>maxang)
cout << " PROBLEM: nside = " << nside << ", ptg = " << ptg << endl;
}
}
}
void check_angpixang2()
{
cout << "testing pix2ang(ang2pix(ptg)) approx ptg" << endl;
for (int order=0; order<=29; ++order)
{
cout << "order = " << order << endl;
Healpix_Base2 base1 (order,NEST);
Healpix_Base2 base2 (order,RING);
double maxang = base1.max_pixrad();
for (int m=0; m<nsamples; ++m)
{
pointing ptg;
random_dir (ptg);
if (v_angle(base1.pix2ang(base1.ang2pix(ptg)),ptg)>maxang)
cout << " PROBLEM: order = " << order << ", ptg = " << ptg << endl;
if (v_angle(base2.pix2ang(base2.ang2pix(ptg)),ptg)>maxang)
cout << " PROBLEM: order = " << order << ", ptg = " << ptg << endl;
}
}
for (int nside=3; nside<(1<<29); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base2 base (nside,RING,SET_NSIDE);
double maxang = base.max_pixrad();
for (int m=0; m<nsamples; ++m)
{
pointing ptg;
random_dir (ptg);
if (v_angle(base.pix2ang(base.ang2pix(ptg)),ptg)>maxang)
cout << " PROBLEM: nside = " << nside << ", ptg = " << ptg << endl;
}
}
}
void check_neighbors()
{
cout << "testing neighbor function" << endl;
for (int order=0; order<=13; ++order)
{
cout << "order = " << order << endl;
Healpix_Base base (order,NEST), base2(order,RING);
double maxang = 2.01*base.max_pixrad();
for (int m=0; m<nsamples/10; ++m)
{
int pix = int(rng.rand_uni()*base.Npix());
fix_arr<int,8> nb;
vec3 pixpt = base.pix2ang(pix);
base.neighbors(pix,nb);
sort(&nb[0],&nb[0]+8);
int check=0;
for (int n=0; n<8; ++n)
{
if (nb[n]<0)
{
++check;
}
else
{
if (v_angle(base.pix2ang(nb[n]),pixpt)>maxang)
cout << " PROBLEM: order = " << order << ", pix = " << pix << endl;
if ((n>0) && (nb[n]==nb[n-1]))
cout << " PROBLEM: order = " << order << ", pix = " << pix << endl;
}
}
planck_assert((check<=1)||((order==0)&&(check<=2)),"too few neighbors");
pixpt = base2.pix2ang(pix);
base2.neighbors(pix,nb);
for (int n=0; n<8; ++n)
if ((nb[n]>=0) && (v_angle(base2.pix2ang(nb[n]),pixpt)>maxang))
cout << " PROBLEM2: order = " << order << ", pix = " << pix << endl;
}
}
for (int nside=3; nside<(1<<13); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base base (nside,RING,SET_NSIDE);
double maxang = 2.01*base.max_pixrad();
for (int m=0; m<nsamples/10; ++m)
{
int pix = int(rng.rand_uni()*base.Npix());
fix_arr<int,8> nb;
vec3 pixpt = base.pix2ang(pix);
base.neighbors(pix,nb);
for (int n=0; n<8; ++n)
if ((nb[n]>=0) && (v_angle(base.pix2ang(nb[n]),pixpt)>maxang))
cout << " PROBLEM: nside = " << nside << ", pix = " << pix << endl;
}
}
}
void check_neighbors2()
{
cout << "testing neighbor function" << endl;
for (int order=0; order<=29; ++order)
{
cout << "order = " << order << endl;
Healpix_Base2 base (order,NEST), base2(order,RING);
double maxang = 2.01*base.max_pixrad();
for (int m=0; m<nsamples/10; ++m)
{
int64 pix = int64(rng.rand_uni()*base.Npix());
fix_arr<int64,8> nb;
vec3 pixpt = base.pix2ang(pix);
base.neighbors(pix,nb);
sort(&nb[0],&nb[0]+8);
int check=0;
for (int n=0; n<8; ++n)
{
if (nb[n]<0)
{
++check;
}
else
{
if (v_angle(base.pix2ang(nb[n]),pixpt)>maxang)
cout << " PROBLEM: order = " << order << ", pix = " << pix << endl;
if ((n>0) && (nb[n]==nb[n-1]))
cout << " PROBLEM: order = " << order << ", pix = " << pix << endl;
}
}
planck_assert((check<=1)||((order==0)&&(check<=2)),"too few neighbors");
pixpt = base2.pix2ang(pix);
base2.neighbors(pix,nb);
for (int n=0; n<8; ++n)
if ((nb[n]>=0) && (v_angle(base2.pix2ang(nb[n]),pixpt)>maxang))
cout << " PROBLEM2: order = " << order << ", pix = " << pix << endl;
}
}
for (int nside=3; nside<(1<<29); nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Base2 base (nside,RING,SET_NSIDE);
double maxang = 2.01*base.max_pixrad();
for (int m=0; m<nsamples/10; ++m)
{
int64 pix = int64(rng.rand_uni()*base.Npix());
fix_arr<int64,8> nb;
vec3 pixpt = base.pix2ang(pix);
base.neighbors(pix,nb);
for (int n=0; n<8; ++n)
if ((nb[n]>=0) && (v_angle(base.pix2ang(nb[n]),pixpt)>maxang))
cout << " PROBLEM: nside = " << nside << ", pix = " << pix << endl;
}
}
}
void check_swap_scheme()
{
cout << "testing whether double swap_scheme() returns the original map"
<< endl << "(for orders 0 to 10)." << endl;
for (int order=0; order<=10; ++order)
{
cout << "order = " << order << endl;
Healpix_Map<uint8> map(order,NEST);
for (int m=0; m<map.Npix(); ++m) map[m]=uint8(m&0xFF);
map.swap_scheme();
map.swap_scheme();
for (int m=0; m<map.Npix(); ++m)
if (map[m]!=(m&0xFF))
cout << " PROBLEM: order = " << order << ", pix = " << m << endl;
}
}
void check_query_disc()
{
cout << "testing whether all pixels found by query_disc() really" << endl
<< "lie inside the disk (and vice versa)" << endl;
for (int order=0; order<=5; ++order)
{
cout << "order = " << order << endl;
Healpix_Map <bool> map (order,RING);
map.fill(false);
vector<int> list;
for (int m=0; m<100000; ++m)
{
pointing ptg;
random_dir (ptg);
double rad = pi/1 * rng.rand_uni();
map.query_disc(ptg,rad,list);
vec3 vptg=ptg;
double cosrad=cos(rad);
for (tsize i=0; i<list.size(); ++i)
map[list[i]] = true;
for (int i=0; i<map.Npix(); ++i)
{
bool inside = dotprod(vec3(map.pix2ang(i)),vptg)>cosrad;
if (inside^map[i])
cout << " PROBLEM: order = " << order << ", ptg = " << ptg << endl;
}
for (tsize i=0; i<list.size(); ++i)
map[list[i]] = false;
}
}
}
void helper_oop (int order)
{
Healpix_Map<double> map (order,RING), map2 (order,NEST), map3 (order,RING);
for (int m=0; m<map.Npix(); ++m) map[m] = rng.rand_uni()+0.01;
map2.Import(map);
map3.Import(map2);
for (int m=0; m<map.Npix(); ++m)
if (!approx(map[m],map3[m],1e-12))
cout << "PROBLEM: order = " << order << endl;
}
void helper_udgrade (int order, Healpix_Ordering_Scheme s1,
Healpix_Ordering_Scheme s2)
{
Healpix_Map<double> map (order,s1), map2 (order+2,s2), map3 (order, s1);
for (int m=0; m<map.Npix(); ++m) map[m] = rng.rand_uni()+0.01;
map2.Import(map);
map3.Import(map2);
for (int m=0; m<map.Npix(); ++m)
if (!approx(map[m],map3[m],1e-12))
cout << "PROBLEM: order = " << order << endl;
}
void helper_udgrade2 (int nside)
{
Healpix_Map<double> map (nside,RING,SET_NSIDE), map2 (nside*3,RING,SET_NSIDE),
map3 (nside, RING,SET_NSIDE);
for (int m=0; m<map.Npix(); ++m) map[m] = rng.rand_uni()+0.01;
map2.Import(map);
map3.Import(map2);
for (int m=0; m<map.Npix(); ++m)
if (!approx(map[m],map3[m],1e-12))
cout << "PROBLEM: nside = " << nside << endl;
}
void check_import()
{
cout << "testing out-of-place swapping" << endl;
for (int order=0; order<=7; ++order)
{
cout << "order = " << order << endl;
helper_oop(order);
}
cout << "testing downgrade(upgrade(map)) == map" << endl;
for (int order=0; order<=7; ++order)
{
cout << "order = " << order << endl;
cout << "RING, RING" << endl;
helper_udgrade(order,RING,RING);
cout << "RING, NEST" << endl;
helper_udgrade(order,RING,NEST);
cout << "NEST, NEST" << endl;
helper_udgrade(order,NEST,NEST);
cout << "NEST, RING" << endl;
helper_udgrade(order,NEST,RING);
}
for (int nside=3; nside<500; nside+=nside/2+1)
{
cout << "nside = " << nside << endl;
helper_udgrade2(nside);
}
}
void check_average()
{
cout << "testing whether average(map) == average(downgraded map)" << endl;
for (int order=1; order<=10; ++order)
{
cout << "order = " << order << endl;
Healpix_Map<double> map (order,RING), map2(1,RING);
for (int m=0; m<map.Npix(); ++m)
map[m] = rng.rand_uni()+0.01;
map2.Import(map);
double avg=map.average(), avg2=map2.average();
if (!approx(avg,avg2,1e-10))
cout << "PROBLEM: order = " << order << " " << avg/avg2-1 << endl;
}
for (int nside=3; nside<1000; nside += nside/2+1)
{
cout << "nside = " << nside << endl;
Healpix_Map<double> map (nside,RING,SET_NSIDE), map2(1,RING,SET_NSIDE);
for (int m=0; m<map.Npix(); ++m)
map[m] = rng.rand_uni()+0.01;
map2.Import(map);
double avg=map.average(), avg2=map2.average();
if (!approx(avg,avg2,1e-10))
cout << "PROBLEM: nside = " << nside << " " << avg/avg2-1 << endl;
}
}
void random_alm (Alm<xcomplex<double> >&almT, Alm<xcomplex<double> >&almG,
Alm<xcomplex<double> >&almC, int lmax, int mmax)
{
almT.Set(lmax,mmax); almG.Set(lmax,mmax); almC.Set(lmax,mmax);
for (int l=0; l<=lmax; ++l)
{
almT(l,0).re=rng.rand_gauss(); almT(l,0).im=0.;
almG(l,0).re=rng.rand_gauss(); almG(l,0).im=0.;
almC(l,0).re=rng.rand_gauss(); almC(l,0).im=0.;
}
for (int m=1; m<=mmax; ++m)
for (int l=m; l<=lmax; ++l)
{
almT(l,m).re=rng.rand_gauss(); almT(l,m).im=rng.rand_gauss();
almG(l,m).re=rng.rand_gauss(); almG(l,m).im=rng.rand_gauss();
almC(l,m).re=rng.rand_gauss(); almC(l,m).im=rng.rand_gauss();
}
almG(0,0)=almC(0,0)=almG(1,0)=almC(1,0)=almG(1,1)=almC(1,1)=0;
}
void random_alm (Alm<xcomplex<double> >&alm, int lmax, int mmax)
{
alm.Set(lmax,mmax);
for (int l=0; l<=lmax; ++l)
{ alm(l,0).re=rng.rand_gauss(); alm(l,0).im=0.; }
for (int m=1; m<=mmax; ++m)
for (int l=m; l<=lmax; ++l)
{ alm(l,m).re=rng.rand_gauss(); alm(l,m).im=rng.rand_gauss(); }
}
void check_alm (const Alm<xcomplex<double> >&oalm,
const Alm<xcomplex<double> >&alm, double epsilon)
{
for (int m=0; m<=alm.Mmax(); ++m)
for (int l=m; l<=alm.Lmax(); ++l)
{
if (!abs_approx(oalm(l,m).re,alm(l,m).re,epsilon))
cout << "Problemr " << l << " " << m << endl;
if (!abs_approx(oalm(l,m).im,alm(l,m).im,epsilon))
cout << "Problemi " << l << " " << m << endl;
}
}
void check_alm2map2alm (int lmax, int mmax, int nside)
{
cout << "testing whether a_lm->map->a_lm returns original a_lm" << endl;
cout << "lmax=" << lmax <<", mmax=" << mmax << ", nside=" << nside << endl;
const double epsilon = 1e-8;
Alm<xcomplex<double> > oalmT(lmax,mmax),almT(lmax,mmax),
oalmG(lmax,mmax),almG(lmax,mmax),oalmC(lmax,mmax),almC(lmax,mmax);
Healpix_Map<double> mapT(nside,RING,SET_NSIDE), mapQ(nside,RING,SET_NSIDE),
mapU(nside,RING,SET_NSIDE);
random_alm(oalmT,oalmG,oalmC,lmax,mmax);
alm2map(oalmT,mapT);
map2alm_iter2(mapT,almT,1e-12,1e-12);
check_alm (oalmT, almT, epsilon);
alm2map_spin(oalmG,oalmC,mapQ,mapU,1);
map2alm_spin_iter2(mapQ,mapU,almG,almC,1,1e-12,1e-12);
check_alm (oalmG, almG, epsilon);
check_alm (oalmC, almC, epsilon);
alm2map_pol(oalmT,oalmG,oalmC,mapT,mapQ,mapU);
map2alm_pol_iter2(mapT,mapQ,mapU,almT,almG,almC,1e-12,1e-12);
check_alm (oalmT, almT, epsilon);
check_alm (oalmG, almG, epsilon);
check_alm (oalmC, almC, epsilon);
}
void check_smooth_alm ()
{
cout << "testing whether unsmooth(smooth(a_lm)) returns a_lm" << endl;
const double epsilon = 1e-14;
const double fwhm = 100.*arcmin2rad;
const int lmax=300, mmax=300;
Alm<xcomplex<double> > oalmT(lmax,mmax),almT(lmax,mmax),
oalmG(lmax,mmax),almG(lmax,mmax),oalmC(lmax,mmax),almC(lmax,mmax);
random_alm(oalmT,oalmG,oalmC,lmax,mmax);
almT=oalmT; almG=oalmG; almC=oalmC;
smoothWithGauss (almT, fwhm);
smoothWithGauss (almT, -fwhm);
check_alm (oalmT, almT, epsilon);
almT=oalmT;
smoothWithGauss (almT, almG, almC, fwhm);
smoothWithGauss (almT, almG, almC, -fwhm);
check_alm (oalmT, almT, epsilon);
check_alm (oalmG, almG, epsilon);
check_alm (oalmC, almC, epsilon);
}
void check_rot_alm ()
{
cout << "testing whether rot^-1(rot(a_lm)) returns a_lm" << endl;
const double epsilon = 2e-13;
const int lmax=300;
Alm<xcomplex<double> > oalm(lmax,lmax),alm(lmax,lmax);
random_alm(oalm,lmax,lmax);
alm=oalm;
rotate_alm (alm,3,4,5);
rotate_alm (alm,-5,-4,-3);
check_alm (oalm, alm, epsilon);
}
} // unnamed namespace
int main(int argc, const char **argv)
{
module_startup ("hpxtest",argc,argv,1,"");
check_smooth_alm();
check_rot_alm();
check_alm2map2alm(620,620,256);
check_alm2map2alm(620,2,256);
check_average();
check_import();
check_neighbors();
check_neighbors2();
check_pixangpix();
check_pixangpix2();
check_pixvecpix();
check_pixvecpix2();
check_angpixang();
check_angpixang2();
check_ringnestring();
check_ringnestring2();
check_nestpeanonest();
check_nestpeanonest2();
check_query_disc();
check_swap_scheme();
}

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
map2tga_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,76 @@
Usage:
map2tga <parameter file>
or:
map2tga <input file> <output file> [-sig <int>] [-pal <int>]
[-xsz <int>] [-bar] [-log] [-asinh] [-lon <float>] [-lat <float>]
[-mul <float>] [-add <float>] [-min <float>] [-max <float>]
[-res <float>] [-title <string>] [-flippal] [-gnomonic]
[-interpol] [-equalize] [-viewer <viewer>]
Parameters read by map2tga:
infile (string):
input file containing the Healpix map
outfile (string):
output TGA file
sig (integer, default=1):
column number of the requested Healpix map
pal (integer, default=4):
number of the color palette
flippal (bool, default=false):
whether the palette should be flipped
xsz (integer, default=1024):
number of image pixels in x direction
bar (logical, default=false):
whether a color bar should be added to the image
log (logical, default=false):
whether the logarithm of the map values should be displayed
equalize (logical, default=false):
whether histogram equalisation should be performed
asinh (logical, default=false):
whether the hyperbolic arcsine of the map values should be displayed
lon (double, default=0):
the longitude (in degrees) of the image center
lat (double, default=0):
the latitude (in degrees) of the image center
mul (double, default=1):
scale factor applied to the data
add (double, default=0):
offset added to the data (before multiplication)
min (double, optional):
if specified, this value is used as minimum of the color scale
max (double, optional):
if specified, this value is used as maximum of the color scale
res (double, default=1):
only for gnomonic projection: the size (in arcmin) of an image pixel
title (string, optional):
if specified, this value is used as the image title
viewer (string, optional):
if specified, this executable is used to show the resulting image
pro (string, default="mollw"):
if this is equal to "gno", gnomonic projection is used, else Mollweide
interpol (bool, default=false):
false: no interpolation
true : bilinear interpolation

View file

@ -0,0 +1,388 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include <sstream>
#include <iomanip>
#include <cstdlib>
#include "healpix_map.h"
#include "healpix_map_fitsio.h"
#include "rotmatrix.h"
#include "pointing.h"
#include "ls_image.h"
#include "paramfile.h"
#include "levels_facilities.h"
#include "lsconstants.h"
using namespace std;
namespace {
void histo_eq (arr2<float> &img, float &minv, float &maxv, arr<double> &newpos)
{
const int nbins=100;
arr<int> bincnt (nbins);
bincnt.fill(0);
int pixels=0;
double fact = 1./(maxv-minv);
for (tsize i=0; i<img.size1(); ++i)
for (tsize j=0; j<img.size2(); ++j)
if (img[i][j]>-1e30)
{
img[i][j] = float((img[i][j]-minv)*fact);
int idx = int(img[i][j]*nbins);
idx=max(0,min(idx,nbins-1));
++bincnt[idx];
++pixels;
}
newpos.alloc(nbins+1);
int accu=0;
for (int m=0; m<nbins; ++m)
{
newpos[m] = double(accu)/pixels;
accu += bincnt[m];
}
newpos[nbins]=1.;
for (tsize i=0; i<img.size1(); ++i)
for (tsize j=0; j<img.size2(); ++j)
if (img[i][j]>-1e30)
{
int idx = int(img[i][j]*nbins);
idx=max(0,min(idx,nbins-1));
double frac = nbins*img[i][j] - idx;
img[i][j] = float((1-frac)*newpos[idx] + frac*newpos[idx+1]);
img[i][j] = float(minv+(maxv-minv)*img[i][j]);
}
}
void pro_mollw (const Healpix_Map<float> &map, double lon0, double lat0,
int xsize, arr2<float> &img, float &minv, float &maxv, bool smooth)
{
int ysize=xsize/2;
img.alloc(xsize,ysize);
img.fill(-1e35);
double xc=(xsize-1)/2., yc=(ysize-1)/2.;
rotmatrix rot;
rot.Make_CPAC_Euler_Matrix(0,-lat0,-lon0);
minv=1e30;
maxv=-1e30;
for (tsize i=0; i<img.size1(); ++i)
for (tsize j=0; j<img.size2(); ++j)
{
double u = 2*(i-xc)/(xc/1.02);
double v = (j-yc)/(yc/1.02);
bool mask = ((u*u/4 + v*v) <= 1);
if (mask)
{
pointing ptg (halfpi-(asin(2/pi*(asin(v) + v*sqrt((1-v)*(1+v))))),
-halfpi*u/max(sqrt((1-v)*(1+v)),1e-6));
vec3 pnt = rot.Transform(ptg.to_vec3());
if (smooth)
img[i][j] = map.interpolated_value(pnt);
else
img[i][j] = map[map.ang2pix(pnt)];
if (!approx<double>(img[i][j],Healpix_undef))
{
if (img[i][j]<minv) minv=img[i][j];
if (img[i][j]>maxv) maxv=img[i][j];
}
}
}
}
void pro_gno (const Healpix_Map<float> &map, double lon0, double lat0,
int xsize, double delta, arr2<float> &img, float &minv, float &maxv,
bool smooth)
{
rotmatrix rot;
rot.Make_CPAC_Euler_Matrix(lon0,-lat0,0);
double start=-(xsize/2.)*delta;
img.alloc(xsize,xsize);
minv=1e30;
maxv=-1e30;
for (tsize i=0; i<img.size1(); ++i)
for (tsize j=0; j<img.size2(); ++j)
{
vec3 pnt (1,-(start+i*delta), start+j*delta);
pnt = rot.Transform(pnt);
if (smooth)
img[i][j] = map.interpolated_value(pnt);
else
img[i][j] = map[map.ang2pix(pnt)];
if (!approx<double>(img[i][j],Healpix_undef))
{
if (img[i][j]<minv) minv=img[i][j];
if (img[i][j]>maxv) maxv=img[i][j];
}
}
}
void colorbar (LS_Image &img, const Palette &pal, int xmin, int xmax,
int ymin, int ymax, bool flippal, const arr<double> &newpos)
{
int nbins = newpos.size()-1;
for (int i=xmin; i<=xmax; ++i)
{
double val = (double(i)-xmin)/(xmax-xmin);
if (nbins>0)
{
int idx = int(val*nbins);
idx=max(0,min(idx,nbins-1));
double frac = nbins*val - idx;
val = (1-frac)*newpos[idx] + frac*newpos[idx+1];
}
if (flippal) val=1-val;
Colour c = pal.Get_Colour(float(val));
for (int j=ymin; j<=ymax; ++j)
img.put_pixel(i,j,c);
}
}
string conv (double val)
{
ostringstream os;
if (abs(val)>100 || abs(val)<0.01)
{
os << setw(10) << setprecision(3) << scientific << val;
return os.str();
}
os << setw(10) << setprecision(6) << fixed << val;
return trim(os.str());
}
void usage()
{
cout <<
"\nUsage:\n"
" map2tga <parameter file>\n\n"
"or:\n"
" map2tga <input file> <output file> [-sig <int>] [-pal <int>]\n"
" [-xsz <int>] [-bar] [-log] [-asinh] [-lon <float>] [-lat <float>]\n"
" [-mul <float>] [-add <float>] [-min <float>] [-max <float>]\n"
" [-res <float>] [-title <string>] [-flippal] [-gnomonic]\n"
" [-interpol] [-equalize] [-viewer <viewer>]\n\n";
planck_fail_quietly("Incorrect usage");
}
} // unnamed namespace
int map2tga_module (int argc, const char **argv)
{
announce ("map2tga");
if (argc<2) usage();
string infile = "";
string outfile = "";
string title = "";
int xres = 1024;
bool bar = false, mollpro=true;
double lat0=0, lon0=0, res=1*arcmin2rad;
float usermin=-1e30, usermax=1e30, offset=0, factor=1;
bool min_supplied=false, max_supplied=false;
bool logflag=false, asinhflag=false, eqflag=false;
int palnr = 4;
int colnum=1;
bool flippal = false;
bool interpol = false;
string viewer = "";
if (argc>2)
{
infile = argv[1];
outfile = argv[2];
int m=3;
while (m<argc)
{
int mstart = m;
string arg = argv[m];
if (arg == "-sig") { stringToData(argv[m+1],colnum); m+=2; }
if (arg == "-pal") { stringToData(argv[m+1],palnr); m+=2; }
if (arg == "-xsz") { stringToData(argv[m+1],xres); m+=2; }
if (arg == "-bar") { bar=true; ++m; }
if (arg == "-log") { logflag=true; ++m; }
if (arg == "-equalize") { eqflag=true; ++m; }
if (arg == "-asinh") { asinhflag=true; ++m; }
if (arg == "-lon") { stringToData(argv[m+1],lon0); lon0*=degr2rad; m+=2; }
if (arg == "-lat") { stringToData(argv[m+1],lat0); lat0*=degr2rad; m+=2; }
if (arg == "-mul") { stringToData(argv[m+1],factor); m+=2; }
if (arg == "-add") { stringToData(argv[m+1],offset); m+=2; }
if (arg == "-min")
{
stringToData(argv[m+1],usermin);
min_supplied=true;
m+=2;
}
if (arg == "-max")
{
stringToData(argv[m+1],usermax);
max_supplied=true;
m+=2;
}
if (arg == "-res")
{ stringToData(argv[m+1],res); res*=arcmin2rad; m+=2; }
if (arg == "-title") { title = argv[m+1]; m+=2; }
if (arg == "-viewer") { viewer = argv[m+1]; m+=2; }
if (arg == "-flippal") { flippal=true; ++m; }
if (arg == "-gnomonic") { mollpro=false; ++m; }
if (arg == "-interpol") { interpol=true; ++m; }
if (mstart==m)
{
cout << "unrecognized option: " + arg << endl;
usage();
}
}
}
else
{
paramfile params (argv[1]);
infile = params.find<string>("infile");
outfile = params.find<string>("outfile");
colnum = params.find<int>("sig",colnum);
palnr = params.find<int>("pal",palnr);
flippal = params.find<bool>("flippal",flippal);
xres = params.find<int>("xsz",xres);
bar = params.find<bool>("bar",bar);
logflag = params.find<bool>("log",logflag);
eqflag = params.find<bool>("equalize",eqflag);
asinhflag = params.find<bool>("asinh",asinhflag);
lon0 = degr2rad*params.find<double>("lon",lon0);
lat0 = degr2rad*params.find<double>("lat",lat0);
factor = params.find<float>("mul",factor);
offset = params.find<float>("add",offset);
usermin = params.find<float>("min", usermin);
if (usermin>-1e29) min_supplied = true;
usermax = params.find<float>("max", usermax);
if (usermax<1e29) max_supplied = true;
res = arcmin2rad*params.find<double>("res",res);
title = params.find<string>("title","");
viewer = params.find<string>("viewer","");
string tmp = params.find<string>("pro","");
if (tmp == "gno") mollpro=false;
interpol = params.find<bool>("interpol",interpol);
}
Healpix_Map<float> map(0,RING);
read_Healpix_map_from_fits(infile,map,colnum,2);
for (int m=0; m<map.Npix(); ++m)
{
if (!approx<double>(map[m],Healpix_undef))
{
map[m] = (map[m]+offset)*factor;
if (logflag)
{
if (map[m]<=0)
map[m] = Healpix_undef;
else
map[m] = float(log(double(map[m]))/ln10);
}
if (asinhflag)
{
if (map[m]>=0)
map[m] = float(log(double(map[m]+sqrt(map[m]*map[m]+1))));
else
map[m] = float(-log(double(-map[m]+sqrt(map[m]*map[m]+1))));
}
if (min_supplied) if (map[m] < usermin) map[m] = usermin;
if (max_supplied) if (map[m] > usermax) map[m] = usermax;
}
}
arr2<float> imgarr;
float minv, maxv;
if (mollpro)
pro_mollw (map,lon0,lat0,xres,imgarr,minv,maxv,interpol);
else
pro_gno (map,lon0,lat0,xres,res,imgarr,minv,maxv,interpol);
arr<double> newpos;
if (eqflag) histo_eq(imgarr,minv,maxv,newpos);
if (min_supplied) minv = usermin;
if (max_supplied) maxv = usermax;
if (maxv==minv) maxv=minv+1e-10f;
int xsz=imgarr.size1();
int ysz=imgarr.size2();
int yofs=ysz;
int scale = max(1,xsz/800);
if (bar) ysz+=60*scale;
if (title != "") { ysz+=50*scale; yofs+=50*scale; }
LS_Image img(xsz,ysz);
img.fill(Colour(1,1,1));
img.set_font (giant_font);
Palette pal;
pal.setPredefined(palnr);
if (title != "")
img.annotate_centered(xsz/2,25*scale,Colour(0,0,0),title,scale);
for (tsize i=0; i<imgarr.size1(); ++i)
for (tsize j=0; j<imgarr.size2(); ++j)
{
if (imgarr[i][j]>-1e32)
{
Colour c(0.5,0.5,0.5);
if (!approx<double>(imgarr[i][j],Healpix_undef))
{
int col = int((imgarr[i][j]-minv)/(maxv-minv)*256);
col = min(255,max(col,0));
float colfrac = (imgarr[i][j]-minv)/(maxv-minv);
if (flippal) colfrac = 1-colfrac;
c = pal.Get_Colour(colfrac);
}
img.put_pixel(i,yofs-j-1,c);
}
}
if (bar)
{
colorbar (img,pal,xsz/10,(xsz*9)/10,ysz-40*scale,ysz-20*scale,flippal,
newpos);
img.set_font (medium_bold_font);
img.annotate_centered (xsz/20,ysz-30*scale,Colour(0,0,0),conv(minv),scale);
img.annotate_centered ((xsz*19)/20,ysz-30*scale,Colour(0,0,0),conv(maxv),
scale);
}
img.write_TGA(outfile);
if (viewer!="")
{
int retcode = system((viewer+" "+outfile).c_str());
if (retcode != 0)
cout << "Warning: viewer return code was " << retcode << endl;
}
return 0;
}

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
median_filter_cxx_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,80 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2005-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "cxxutils.h"
#include "healpix_map.h"
#include "healpix_map_fitsio.h"
#include "fitshandle.h"
#include "levels_facilities.h"
#include "lsconstants.h"
using namespace std;
namespace {
template<typename Iterator> typename iterator_traits<Iterator>::value_type
median(Iterator first, Iterator last)
{
Iterator mid = first+(last-first-1)/2;
nth_element(first,mid,last);
if ((last-first)&1) return *mid;
return typename iterator_traits<Iterator>::value_type
(0.5*((*mid)+(*min_element(mid+1,last))));
}
} // unnamed namespace
int median_filter_cxx_module (int argc, const char **argv)
{
module_startup ("median_filter_cxx", argc, argv, 4,
"<input map> <output map> <radius in arcmin>");
double radius = stringToData<double>(argv[3])*arcmin2rad;
Healpix_Map<float> inmap;
read_Healpix_map_from_fits(argv[1],inmap,1,2);
Healpix_Map<float> outmap (inmap.Nside(), inmap.Scheme(), SET_NSIDE);
vector<int> list;
vector<float> list2;
for (int m=0; m<inmap.Npix(); ++m)
{
inmap.query_disc(inmap.pix2ang(m),radius,list);
list2.resize(list.size());
for (tsize i=0; i<list.size(); ++i)
list2[i] = inmap[list[i]];
outmap[m]=median(list2.begin(),list2.end());
}
write_Healpix_map_to_fits (argv[2],outmap,PLANCK_FLOAT32);
return 0;
}

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
mult_alm_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,32 @@
Parameters read by mult_alm:
infile (string):
input file containing the a_lm
outfile (string):
output file name for the calculated a_lm
fwhm_arcmin_in (real, default=0):
FWHM (in arcmin) of a Gaussian beam, which will be _removed_ from the
input a_lm
fwhm_arcmin_out (real, default=0):
FWHM (in arcmin) of a Gaussian beam, which will be used to smoothe the
output a_lm
nside_pixwin_in (integer, default=0):
If this is different from 0, the corresponding pixel window function
will be _removed_ from the input a_lm
nside_pixwin_out (integer, default=0):
If this is different from 0, the corresponding pixel window function
will be applied to the output a_lm
if ((nside_pixwin_in>0)||(nside_pixwin_out>0))
healpix_data (string):
directory containing the Healpix data files
endif
double_precision (bool, default=false):
if false, the a_lm are read/written in single precision,
otherwise in double precision.

View file

@ -0,0 +1,124 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "xcomplex.h"
#include "cxxutils.h"
#include "paramfile.h"
#include "healpix_data_io.h"
#include "alm.h"
#include "alm_fitsio.h"
#include "alm_powspec_tools.h"
#include "fitshandle.h"
#include "levels_facilities.h"
#include "lsconstants.h"
using namespace std;
namespace {
template<typename T> void mult_alm (paramfile &params)
{
string infile = params.template find<string>("infile");
string outfile = params.template find<string>("outfile");
int nside_pixwin_in = params.template find<int>("nside_pixwin_in",0);
planck_assert (nside_pixwin_in>=0,"nside_pixwin_in must be >= 0");
int nside_pixwin_out = params.template find<int>("nside_pixwin_out",0);
planck_assert (nside_pixwin_out>=0,"nside_pixwin_out must be >= 0");
double fwhm_in = arcmin2rad*params.template find<double>("fwhm_arcmin_in",0);
planck_assert (fwhm_in>=0,"fwhm_arcmin_in must be >= 0");
double fwhm_out = arcmin2rad*params.template find<double>("fwhm_arcmin_out",0);
planck_assert (fwhm_out>=0,"fwhm_arcmin_out must be >= 0");
string datadir;
if ((nside_pixwin_in>0) || (nside_pixwin_out>0))
datadir = params.template find<string>("healpix_data");
bool polarisation = params.template find<bool>("polarisation");
if (!polarisation)
{
int nlmax, nmmax;
get_almsize(infile, nlmax, nmmax, 2);
Alm<xcomplex<T> > alm;
read_Alm_from_fits(infile,alm,nlmax,nmmax,2);
if (fwhm_in>0) smoothWithGauss (alm, -fwhm_in);
arr<double> temp(nlmax+1);
if (nside_pixwin_in>0)
{
read_pixwin(datadir,nside_pixwin_in,temp);
for (int l=0; l<=nlmax; ++l)
temp[l] = 1/temp[l];
alm.ScaleL (temp);
}
if (nside_pixwin_out>0)
{
read_pixwin(datadir,nside_pixwin_out,temp);
alm.ScaleL (temp);
}
if (fwhm_out>0) smoothWithGauss (alm, fwhm_out);
write_Alm_to_fits (outfile,alm,nlmax,nmmax,planckType<T>());
}
else
{
int nlmax, nmmax;
get_almsize_pol(infile, nlmax, nmmax);
Alm<xcomplex<T> > almT, almG, almC;
read_Alm_from_fits(infile,almT,almG,almC,nlmax,nmmax,2);
if (fwhm_in>0) smoothWithGauss (almT, almG, almC, -fwhm_in);
arr<double> temp(nlmax+1), pol(nlmax+1);
if (nside_pixwin_in>0)
{
read_pixwin(datadir,nside_pixwin_in,temp,pol);
for (int l=0; l<=nlmax; ++l)
{ temp[l] = 1/temp[l]; pol[l] = 1/pol[l]; }
almT.ScaleL(temp); almG.ScaleL(pol); almC.ScaleL(pol);
}
if (nside_pixwin_out>0)
{
read_pixwin(datadir,nside_pixwin_out,temp,pol);
almT.ScaleL(temp); almG.ScaleL(pol); almC.ScaleL(pol);
}
if (fwhm_out>0) smoothWithGauss (almT, almG, almC, fwhm_out);
write_Alm_to_fits (outfile,almT,almG,almC,nlmax,nmmax,planckType<T>());
}
}
} // unnamed namespace
int mult_alm_module (int argc, const char **argv)
{
module_startup ("mult_alm", argc, argv, 2, "<parameter file>");
paramfile params (argv[1]);
bool dp = params.find<bool> ("double_precision",false);
dp ? mult_alm<double>(params) : mult_alm<float>(params);
return 0;
}

View file

@ -0,0 +1,27 @@
PKG:=Healpix_cxx
SD:=$(SRCROOT)/$(PKG)
OD:=$(BLDROOT)/$(PKG)
FULL_INCLUDE+= -I$(SD)
HDR_$(PKG):=$(SD)/*.h
LIB_$(PKG):=$(LIBDIR)/libhealpix_cxx.a
CXXBIN:=syn_alm_cxx alm2map_cxx anafast_cxx map2tga udgrade_cxx hotspots_cxx calc_powspec median_filter_cxx hpxtest smoothing_cxx mult_alm rotalm_cxx
LIBOBJ:=alm_powspec_tools.o powspec.o alm_fitsio.o powspec_fitsio.o healpix_base.o healpix_map.o alm_healpix_tools.o healpix_data_io.o healpix_map_fitsio.o healpix_base2.o syn_alm_cxx_module.o anafast_cxx_module.o alm2map_cxx_module.o map2tga_module.o udgrade_cxx_module.o smoothing_cxx_module.o hotspots_cxx_module.o calc_powspec_module.o median_filter_cxx_module.o mult_alm_module.o
ALLOBJ:=$(LIBOBJ) $(CXXBIN:%=%.o)
LIBOBJ:=$(LIBOBJ:%=$(OD)/%)
ALLOBJ:=$(ALLOBJ:%=$(OD)/%)
ODEP:=$(HDR_$(PKG)) $(HDR_cxxsupport) $(HDR_libpsht) $(HDR_libfftpack) $(HDR_c_utils)
BDEP:=$(LIB_$(PKG)) $(LIB_cxxsupport) $(LIB_libpsht) $(LIB_libfftpack) $(LIB_c_utils) $(LIB_libcfitsio)
$(LIB_$(PKG)): $(LIBOBJ)
$(ALLOBJ): $(ODEP) | $(OD)_mkdir
CXXBIN:=$(CXXBIN:%=$(BINDIR)/%)
$(CXXBIN): $(BINDIR)/% : $(OD)/%.o $(BDEP)
all_hdr+=$(HDR_$(PKG))
all_lib+=$(LIB_$(PKG))
all_cxxbin+=$(CXXBIN)

132
external/healpix/Healpix_cxx/powspec.cc vendored Normal file
View file

@ -0,0 +1,132 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "powspec.h"
#include "lsconstants.h"
using namespace std;
void PowSpec::dealloc()
{
tt_.dealloc();
gg_.dealloc();
cc_.dealloc();
tg_.dealloc();
tc_.dealloc();
gc_.dealloc();
}
void PowSpec::assertArraySizes() const
{
planck_assert((num_specs==1) || (num_specs==4) || (num_specs==6),
"incorrect number of spectral components");
if (num_specs==1)
planck_assert(multiequal(tsize(0),gg_.size(),cc_.size(),tg_.size(),
tc_.size(),gc_.size()), "incorrect array sizes");
if (num_specs==4)
{
planck_assert(multiequal(tt_.size(),gg_.size(),cc_.size(),tg_.size()),
"incorrect array sizes");
planck_assert(multiequal(tsize(0),tc_.size(),gc_.size()),
"incorrect array sizes");
}
if (num_specs==6)
planck_assert(multiequal(tt_.size(),gg_.size(),cc_.size(),tg_.size(),
tc_.size(),gc_.size()), "incorrect array sizes");
}
bool PowSpec::consistentAutoPowspec() const
{
for (tsize l=0; l<tt_.size(); ++l)
if (tt_[l]<0) return false;
if (num_specs>=4)
for (tsize l=0; l<tt_.size(); ++l)
{
if (gg_[l]<0) return false;
if (cc_[l]<0) return false;
if (abs(tg_[l])>sqrt(tt_[l]*gg_[l])) return false;
}
if (num_specs==6)
for (tsize l=0; l<tt_.size(); ++l)
{
if (abs(tc_[l])>sqrt(tt_[l]*cc_[l])) return false;
if (abs(gc_[l])>sqrt(gg_[l]*cc_[l])) return false;
}
return true;
}
void PowSpec::Set(arr<double> &tt_new)
{
dealloc();
num_specs = 1;
tt_.transfer(tt_new);
//FIXME: temporarily relaxed to allow cross-spectra
if (!consistentAutoPowspec())
cerr << "Warning: negative values in TT spectrum" << endl;
}
void PowSpec::Set(arr<double> &tt_new, arr<double> &gg_new,
arr<double> &cc_new, arr<double> &tg_new)
{
dealloc();
num_specs = 4;
tt_.transfer(tt_new); gg_.transfer(gg_new);
cc_.transfer(cc_new); tg_.transfer(tg_new);
assertArraySizes();
}
void PowSpec::Set(arr<double> &tt_new, arr<double> &gg_new, arr<double> &cc_new,
arr<double> &tg_new, arr<double> &tc_new, arr<double> &gc_new)
{
Set (tt_new, gg_new, cc_new, tg_new);
num_specs = 6;
tc_.transfer(tc_new); gc_.transfer(gc_new);
assertArraySizes();
}
void PowSpec::smoothWithGauss (double fwhm)
{
planck_assert (num_specs<=4, "not yet implemented for num_specs>4");
double sigma = fwhm*fwhm2sigma;
double fact_pol = exp(2*sigma*sigma);
for (tsize l=0; l<tt_.size(); ++l)
{
double f1 = exp(-.5*l*(l+1)*sigma*sigma);
double f2 = f1*fact_pol;
tt_[l] *= f1*f1;
if (num_specs>1)
{
gg_[l] *= f2*f2;
cc_[l] *= f2*f2;
tg_[l] *= f1*f2;
}
}
}

138
external/healpix/Healpix_cxx/powspec.h vendored Normal file
View file

@ -0,0 +1,138 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#ifndef POWSPEC_H
#define POWSPEC_H
#include "arr.h"
/*! Class for storing unpolarised and polarised power spectra. */
class PowSpec
{
private:
arr<double> tt_, gg_, cc_, tg_, tc_, gc_;
int num_specs;
void dealloc();
public:
/*! */
PowSpec() {}
/*! Constructs a \a PowSpec with \a nspec components and a maximum
multipole of \a lmax. \a nspec can be 1 (TT), 4 (TT,GG,CC,TG) or
6 (TT,GG,CC,TG,TC,GC). */
PowSpec(int nspec, int lmax)
: num_specs(nspec)
{
planck_assert ((num_specs==1) || (num_specs==4) || (num_specs==6),
"wrong number of spectrums");
tt_.alloc(lmax+1);
if (num_specs>1)
{
gg_.alloc(lmax+1);
cc_.alloc(lmax+1);
tg_.alloc(lmax+1);
}
if (num_specs>4)
{
tc_.alloc(lmax+1);
gc_.alloc(lmax+1);
}
}
/*! Ensures that the internal array sizes are consistent with the
\a num_specs variable. */
void assertArraySizes() const;
/*! Checks whether the object can be an auto power spectrum. If this
is not the case, an exception is thrown. */
bool consistentAutoPowspec() const;
/*! Returns the number of spectral components. */
int Num_specs() const { return num_specs; }
/*! Returns the maximum \a l. */
int Lmax() const { return tt_.size()-1; }
/*! Returns the TT array (read-only). */
const arr<double> &tt() const { return tt_; }
/*! Returns the GG array (read-only). */
const arr<double> &gg() const { return gg_; }
/*! Returns the CC array (read-only). */
const arr<double> &cc() const { return cc_; }
/*! Returns the TG array (read-only). */
const arr<double> &tg() const { return tg_; }
/*! Returns the TC array (read-only). */
const arr<double> &tc() const { return tc_; }
/*! Returns the GC array (read-only). */
const arr<double> &gc() const { return gc_; }
/*! Returns TT(l) (read-write). */
double &tt (int l) { return tt_[l]; }
/*! Returns GG(l) (read-write). */
double &gg (int l) { return gg_[l]; }
/*! Returns CC(l) (read-write). */
double &cc (int l) { return cc_[l]; }
/*! Returns TG(l) (read-write). */
double &tg (int l) { return tg_[l]; }
/*! Returns TC(l) (read-write). */
double &tc (int l) { return tc_[l]; }
/*! Returns GC(l) (read-write). */
double &gc (int l) { return gc_[l]; }
/*! Returns TT(l) (read-only). */
const double &tt (int l) const { return tt_[l]; }
/*! Returns GG(l) (read-only). */
const double &gg (int l) const { return gg_[l]; }
/*! Returns CC(l) (read-only). */
const double &cc (int l) const { return cc_[l]; }
/*! Returns TG(l) (read-only). */
const double &tg (int l) const { return tg_[l]; }
/*! Returns TC(l) (read-only). */
const double &tc (int l) const { return tc_[l]; }
/*! Returns GC(l) (read-only). */
const double &gc (int l) const { return gc_[l]; }
/*! Sets the whole TT array.
\note On exit, \a tt_new is zero-sized! */
void Set(arr<double> &tt_new);
/*! Sets the four first components.
\note On exit, all arguments are zero-sized! */
void Set(arr<double> &tt_new, arr<double> &gg_new,
arr<double> &cc_new, arr<double> &tg_new);
/*! Sets all components.
\note On exit, all arguments are zero-sized! */
void Set(arr<double> &tt_new, arr<double> &gg_new,
arr<double> &cc_new, arr<double> &tg_new,
arr<double> &tc_new, arr<double> &gc_new);
/*! Smooths the spectrum with a Gaussian beam.
\a fwhm is given in radian.
\note This is only implememted for 1 and 4 spectra so far. */
void smoothWithGauss (double fwhm);
};
#endif

View file

@ -0,0 +1,113 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "powspec_fitsio.h"
#include "powspec.h"
#include "fitshandle.h"
using namespace std;
void read_powspec_from_fits (const string &infile, PowSpec &powspec,
int nspecs, int lmax)
{
planck_assert ((nspecs==1)||(nspecs==4)||(nspecs==6),
"wrong number of spectra");
fitshandle inp;
inp.open(infile);
inp.goto_hdu(2);
arr<double> tt(lmax+1,0),gg(lmax+1,0),cc(lmax+1,0),tg(lmax+1,0),
tc(lmax+1,0),gc(lmax+1,0);
int lmax_file = safe_cast<int>(inp.nelems(1)-1);
if (lmax_file<lmax)
cerr << "warning: lmax in file smaller than expected; padding with 0."
<< endl;
int lmax_read = min (lmax,lmax_file);
inp.read_column_raw (1,&tt[0],lmax_read+1);
if (nspecs>=4)
{
inp.read_column_raw (2,&gg[0],lmax_read+1);
inp.read_column_raw (3,&cc[0],lmax_read+1);
inp.read_column_raw (4,&tg[0],lmax_read+1);
}
if (nspecs==6)
{
inp.read_column_raw (5,&tc[0],lmax_read+1);
inp.read_column_raw (6,&gc[0],lmax_read+1);
}
if (nspecs==1) powspec.Set(tt);
if (nspecs==4) powspec.Set(tt,gg,cc,tg);
if (nspecs==6) powspec.Set(tt,gg,cc,tg,tc,gc);
}
void write_powspec_to_fits (fitshandle &out,
const PowSpec &powspec, int nspecs)
{
planck_assert ((nspecs==1)||(nspecs==4)||(nspecs==6),
"incorrect number of spectra");
vector<fitscolumn> cols;
cols.push_back(fitscolumn("Temperature C_l","unknown",1,PLANCK_FLOAT64));
if (nspecs>1)
{
cols.push_back(fitscolumn("E-mode C_l","unknown",1,PLANCK_FLOAT64));
cols.push_back(fitscolumn("B-mode C_l","unknown",1,PLANCK_FLOAT64));
cols.push_back(fitscolumn("T-E cross-corr.","unknown",1,
PLANCK_FLOAT64));
}
if (nspecs>4)
{
cols.push_back(fitscolumn("T-B cross-corr.","unknown",1,PLANCK_FLOAT64));
cols.push_back(fitscolumn("E-B cross-corr.","unknown",1,PLANCK_FLOAT64));
}
out.insert_bintab(cols);
out.write_column(1,powspec.tt());
if (nspecs>1)
{
out.write_column(2,powspec.gg());
out.write_column(3,powspec.cc());
out.write_column(4,powspec.tg());
}
if (nspecs>4)
{
out.write_column(5,powspec.tc());
out.write_column(6,powspec.gc());
}
}
void write_powspec_to_fits (const string &outfile,
const PowSpec &powspec, int nspecs)
{
fitshandle out;
out.create(outfile);
write_powspec_to_fits(out,powspec,nspecs);
}

View file

@ -0,0 +1,61 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file powspec_fitsio.h
* Copyright (C) 2003-2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef POWSPEC_FITSIO_H
#define POWSPEC_FITSIO_H
#include <string>
class fitshandle;
class PowSpec;
/*! \defgroup powspec_fitsio_group FITS-based I/O of power spectra */
/*! \{ */
/*! Opens the FITS file \a filename, jumps to HDU 2, and reads \a nspecs
columns into \a powspec. \a nspecs must be 1, 4, or 6. */
void read_powspec_from_fits (const std::string &infile,
PowSpec &powspec, int nspecs, int lmax);
/*! Inserts a new binary table into \a out, which contains \a nspecs columns
of FITS type TDOUBLE, and writes the components of \a powspec into it.
\a nspecs must be 1, 4, or 6. */
void write_powspec_to_fits (fitshandle &out,
const PowSpec &powspec, int nspecs);
/*! Creates a new FITS file called \a outfile, inserts a binary table,
which contains \a nspecs columns of FITS type TDOUBLE, and writes the
components of \a powspec into it. \a nspecs must be 1, 4, or 6. */
void write_powspec_to_fits (const std::string &outfile,
const PowSpec &powspec, int nspecs);
/*! \} */
#endif

View file

@ -0,0 +1,124 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2005 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "alm.h"
#include "alm_fitsio.h"
#include "fitshandle.h"
#include "alm_powspec_tools.h"
#include "trafos.h"
using namespace std;
namespace {
Trafo maketrafo (int num)
{
switch (num)
{
case 1: return Trafo(2000,2000,Equatorial,Galactic);
case 2: return Trafo(2000,2000,Galactic,Equatorial);
case 3: return Trafo(2000,2000,Equatorial,Ecliptic);
case 4: return Trafo(2000,2000,Ecliptic,Equatorial);
case 5: return Trafo(2000,2000,Ecliptic,Galactic);
case 6: return Trafo(2000,2000,Galactic,Ecliptic);
case 7: return Trafo(1950,1950,Equatorial,Galactic);
case 8: return Trafo(1950,1950,Galactic,Equatorial);
case 9: return Trafo(1950,1950,Equatorial,Ecliptic);
case 10: return Trafo(1950,1950,Ecliptic,Equatorial);
case 11: return Trafo(1950,1950,Ecliptic,Galactic);
case 12: return Trafo(1950,1950,Galactic,Ecliptic);
default: planck_fail("Unsupported transformation "+dataToString(num));
}
}
} // unnamed namespace
int main(int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
announce ("rotalm_cxx");
if (argc!=5)
{
cout << "Usage: rotalm_cxx <infile> <outfile> <itransform> <pol>"
<< endl
<< "Transform 1: Equatorial (2000) -> Galactic (2000)" << endl
<< " 2: Galactic (2000) -> Equatorial (2000)" << endl
<< " 3: Equatorial (2000) -> Ecliptic (2000)" << endl
<< " 4: Ecliptic (2000) -> Equatorial (2000)" << endl
<< " 5: Ecliptic (2000) -> Galactic (2000)" << endl
<< " 6: Galactic (2000) -> Ecliptic (2000)" << endl
<< " 7: Equatorial (1950) -> Galactic (1950)" << endl
<< " 8: Galactic (1950) -> Equatorial (1950)" << endl
<< " 9: Equatorial (1950) -> Ecliptic (1950)" << endl
<< " 10: Ecliptic (1950) -> Equatorial (1950)" << endl
<< " 11: Ecliptic (1950) -> Galactic (1950)" << endl
<< " 12: Galactic (1950) -> Ecliptic (1950)" << endl
<< endl
<< "pol: T or F" << endl << endl;
planck_fail_quietly("Incorrect usage");
}
string infile = argv[1];
string outfile = argv[2];
int trafo = stringToData<int>(argv[3]);
bool polarisation = stringToData<bool>(argv[4]);
Trafo tr(maketrafo(trafo));
fitshandle out;
out.create (outfile);
Alm<xcomplex<double> > almT,almG,almC;
if (!polarisation)
{
int lmax, dummy;
get_almsize (infile,lmax,dummy);
read_Alm_from_fits (infile, almT, lmax, lmax);
rotate_alm(almT,tr.Matrix());
write_Alm_to_fits (out,almT,lmax,lmax,PLANCK_FLOAT32);
}
else
{
int lmax, dummy;
get_almsize_pol (infile,lmax,dummy);
read_Alm_from_fits (infile, almT, lmax, lmax, 2);
read_Alm_from_fits (infile, almG, lmax, lmax, 3);
read_Alm_from_fits (infile, almC, lmax, lmax, 4);
rotate_alm(almT,almG,almC,tr.Matrix());
write_Alm_to_fits (out,almT,lmax,lmax,PLANCK_FLOAT64);
write_Alm_to_fits (out,almG,lmax,lmax,PLANCK_FLOAT64);
write_Alm_to_fits (out,almC,lmax,lmax,PLANCK_FLOAT64);
}
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
smoothing_cxx_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,34 @@
Parameters read by smoothing_cxx:
fwhm_arcmin (double):
FWHM (in arcmin) of the Gaussian beam used for smoothing. If the value
is negative, the smoothing of a Gaussian beam with an FWHM of -fwhm_arcmin
will be _removed_ from the input map.
nlmax (integer):
maximum order of l
infile (string):
input file containing the Healpix map
outfile (string, default=""):
output file for the smoothed Healpix map
polarisation (bool):
if false, only an intensity map is smoothed
if true, an IQU map is smoothed
weighted (bool, default=false):
if true, weighted quadrature is used
if (weighted)
healpix_data (string):
directory containing the Healpix data files
endif
iter_order (integer, default=0)
number of iterations for the analysis (0: standard analysis)
double_precision (bool, default=false):
if false, a_lm are read/written in single precision, otherwise in
double precision.

View file

@ -0,0 +1,114 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2005-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "xcomplex.h"
#include "cxxutils.h"
#include "paramfile.h"
#include "healpix_data_io.h"
#include "alm.h"
#include "healpix_map.h"
#include "healpix_map_fitsio.h"
#include "alm_healpix_tools.h"
#include "alm_powspec_tools.h"
#include "fitshandle.h"
#include "levels_facilities.h"
#include "lsconstants.h"
using namespace std;
namespace {
template<typename T> void smoothing_cxx (paramfile &params)
{
int nlmax = params.template find<int>("nlmax");
string infile = params.template find<string>("infile");
string outfile = params.template find<string>("outfile");
bool polarisation = params.template find<bool>("polarisation");
int num_iter = params.template find<int>("iter_order",0);
double fwhm = arcmin2rad*params.template find<double>("fwhm_arcmin");
if (fwhm<0)
cout << "NOTE: negative FWHM supplied, doing a deconvolution..." << endl;
if (!polarisation)
{
Healpix_Map<T> map;
read_Healpix_map_from_fits(infile,map,1,2);
arr<double> weight;
get_ring_weights (params,map.Nside(),weight);
Alm<xcomplex<T> > alm(nlmax,nlmax);
double avg=map.average();
map.Add(T(-avg));
if (map.Scheme()==NEST) map.swap_scheme();
map2alm_iter(map,alm,num_iter,weight);
smoothWithGauss (alm, fwhm);
alm2map(alm,map);
map.Add(T(avg));
write_Healpix_map_to_fits (outfile,map,planckType<T>());
}
else
{
Healpix_Map<T> mapT, mapQ, mapU;
read_Healpix_map_from_fits(infile,mapT,mapQ,mapU);
arr<double> weight;
get_ring_weights (params,mapT.Nside(),weight);
Alm<xcomplex<T> > almT(nlmax,nlmax), almG(nlmax,nlmax), almC(nlmax,nlmax);
double avg=mapT.average();
mapT.Add(T(-avg));
if (mapT.Scheme()==NEST) mapT.swap_scheme();
if (mapQ.Scheme()==NEST) mapQ.swap_scheme();
if (mapU.Scheme()==NEST) mapU.swap_scheme();
map2alm_pol_iter
(mapT,mapQ,mapU,almT,almG,almC,num_iter,weight);
smoothWithGauss (almT, almG, almC, fwhm);
alm2map_pol(almT,almG,almC,mapT,mapQ,mapU);
mapT.Add(T(avg));
write_Healpix_map_to_fits (outfile,mapT,mapQ,mapU,planckType<T>());
}
}
} // unnamed namespace
int smoothing_cxx_module (int argc, const char **argv)
{
module_startup ("smoothing_cxx", argc, argv, 2, "<parameter file>");
paramfile params (argv[1]);
bool dp = params.find<bool> ("double_precision",false);
dp ? smoothing_cxx<double>(params) : smoothing_cxx<float>(params);
return 0;
}

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
syn_alm_cxx_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,28 @@
Parameters read by syn_alm_cxx:
nlmax (integer):
maximum order of l
nmmax (integer):
maximum order of m (must not be larger than nlmax, default=nlmax)
infile (string):
input file containing the CMB power spectrum
outfile (string):
output file name for the calculated a_lm
rand_seed (integer):
random-number seed
fwhm_arcmin (real):
FWHM (in arcmin) of a Gaussian beam, which is used to smooth the
resulting sky a_lm (default=0)
polarisation (bool):
if false, only the intensity a_lm are generated,
if true, T, G and C a_lm are generated
double_precision (bool, default=false):
if false, the a_lm are created in single precision,
otherwise in double precision.

View file

@ -0,0 +1,92 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "xcomplex.h"
#include "cxxutils.h"
#include "paramfile.h"
#include "planck_rng.h"
#include "alm.h"
#include "alm_fitsio.h"
#include "powspec.h"
#include "powspec_fitsio.h"
#include "alm_powspec_tools.h"
#include "fitshandle.h"
#include "levels_facilities.h"
#include "lsconstants.h"
using namespace std;
namespace {
template<typename T> void syn_alm_cxx (paramfile &params)
{
int nlmax = params.template find<int>("nlmax");
int nmmax = params.template find<int>("nmmax",nlmax);
planck_assert(nmmax<=nlmax,"nmmax must not be larger than nlmax");
string infile = params.template find<string>("infile");
string outfile = params.template find<string>("outfile");
int rand_seed = params.template find<int>("rand_seed");
double fwhm = arcmin2rad*params.template find<double>("fwhm_arcmin",0.);
bool polarisation = params.template find<bool>("polarisation");
PowSpec powspec;
int nspecs = polarisation ? 4 : 1;
read_powspec_from_fits (infile, powspec, nspecs, nlmax);
powspec.smoothWithGauss(fwhm);
planck_rng rng(rand_seed);
if (polarisation)
{
Alm<xcomplex<T> >
almT(nlmax,nmmax), almG(nlmax,nmmax), almC(nlmax,nmmax);
create_alm_pol (powspec, almT, almG, almC, rng);
write_Alm_to_fits(outfile,almT,almG,almC,nlmax,nmmax,planckType<T>());
}
else
{
Alm<xcomplex<T> > almT(nlmax,nmmax);
create_alm (powspec, almT, rng);
write_Alm_to_fits(outfile,almT,nlmax,nmmax,planckType<T>());
}
}
} // unnamed namespace
int syn_alm_cxx_module (int argc, const char **argv)
{
module_startup ("syn_alm_cxx", argc, argv, 2, "<parameter file>");
paramfile params (argv[1]);
bool dp = params.find<bool> ("double_precision",false);
dp ? syn_alm_cxx<double>(params) : syn_alm_cxx<float>(params);
return 0;
}

View file

@ -0,0 +1,9 @@
#include "levels_facilities.h"
#include "error_handling.h"
int main (int argc, const char **argv)
{
PLANCK_DIAGNOSIS_BEGIN
udgrade_cxx_module (argc, argv);
PLANCK_DIAGNOSIS_END
}

View file

@ -0,0 +1,88 @@
/*
* This file is part of Healpix_cxx.
*
* Healpix_cxx 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.
*
* Healpix_cxx is distributed in the hope that 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 Healpix_cxx; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* For more information about HEALPix, see http://healpix.jpl.nasa.gov
*/
/*
* Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2003-2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "cxxutils.h"
#include "paramfile.h"
#include "healpix_map.h"
#include "healpix_map_fitsio.h"
#include "fitshandle.h"
#include "levels_facilities.h"
using namespace std;
namespace {
template<typename T> void udgrade_cxx (paramfile &params)
{
string infile = params.template find<string>("infile");
string outfile = params.template find<string>("outfile");
int order = Healpix_Base::nside2order (params.template find<int>("nside"));
bool polarisation = params.template find<bool>("polarisation",false);
bool pessimistic = params.template find<bool>("pessimistic",false);
if (!polarisation)
{
Healpix_Map<T> inmap;
read_Healpix_map_from_fits(infile,inmap,1,2);
Healpix_Map<T> outmap (order, inmap.Scheme());
outmap.Import(inmap,pessimistic);
write_Healpix_map_to_fits (outfile,outmap,planckType<T>());
}
else
{
Healpix_Map<T> inmap;
read_Healpix_map_from_fits(infile,inmap,1,2);
Healpix_Map<T> outmapT (order, inmap.Scheme()),
outmapQ (order, inmap.Scheme()),
outmapU (order, inmap.Scheme());
outmapT.Import(inmap,pessimistic);
read_Healpix_map_from_fits(infile,inmap,2,2);
outmapQ.Import(inmap,pessimistic);
read_Healpix_map_from_fits(infile,inmap,3,2);
outmapU.Import(inmap,pessimistic);
write_Healpix_map_to_fits (outfile,outmapT,outmapQ,outmapU,planckType<T>());
}
}
} // unnamed namespace
int udgrade_cxx_module (int argc, const char **argv)
{
module_startup ("udgrade_cxx", argc, argv, 2, "<parameter file>");
paramfile params (argv[1]);
bool dp = params.find<bool> ("double_precision",false);
dp ? udgrade_cxx<double>(params) : udgrade_cxx<float>(params);
return 0;
}

54
external/healpix/Makefile vendored Normal file
View file

@ -0,0 +1,54 @@
ifndef HEALPIX_TARGET
HEALPIX_TARGET:=$(error HEALPIX_TARGET undefined. Please see README.compilation for help)UNDEFINED
endif
default: compile_all
SRCROOT:=$(shell pwd)
include $(SRCROOT)/config/config.$(HEALPIX_TARGET)
include $(SRCROOT)/config/rules.common
.SILENT:
.PHONY: test
all_hdr:=
all_lib:=
all_cbin:=
all_cxxbin:=
FULL_INCLUDE:=
include libcfitsio/planck.make
include c_utils/planck.make
include libfftpack/planck.make
include libpsht/planck.make
include cxxsupport/planck.make
include Healpix_cxx/planck.make
#include alice/planck.make
#include docsrc/planck.make
$(all_lib): %: | $(LIBDIR)_mkdir
@echo "# creating library $*"
$(ARCREATE) $@ $^
$(all_cxxbin): %: | $(BINDIR)_mkdir
@echo "# linking C++ binary $*"
$(CXXL) $(CXXLFLAGS) -o $@ $^ $(CXX_EXTRALIBS)
$(all_cbin): %: | $(BINDIR)_mkdir
@echo "# linking C binary $*"
$(CXXL) $(CXXLFLAGS) -o $@ $^ $(CXX_EXTRALIBS)
compile_all: $(all_cbin) $(all_cxxbin) hdrcopy
hdrclean:
@if [ -d $(INCDIR) ]; then rm -rf $(INCDIR)/* ; fi
hdrcopy: | $(INCDIR)_mkdir
@if [ "$(all_hdr)" ]; then cp -f $(all_hdr) $(INCDIR); fi
$(notdir $(all_cbin) $(all_cxxbin)) : % : $(BINDIR)/%
$(notdir $(all_lib)) libcfitsio.a : % : $(LIBDIR)/%
test: compile_all
cd test; ./runtest.sh

45
external/healpix/README.compilation vendored Normal file
View file

@ -0,0 +1,45 @@
Starting with HEALPix 2.20, Healpix_cxx supports compilation using a
pre-installed libcfitsio. In order to use this feature, simply set
the following environment variables before running "make":
EXTERNAL_CFITSIO=yes
CFITSIO_EXT_LIB=<full name including path of the cfitsio library file>
CFITSIO_EXT_INC=<full name of a directory containing fitsio.h and longnam.h>
The installed version of libcfitsio should be at least 3.23.
Alternatively, Healpix_cxx can be instructed to compile its own libcfitsio.
For that purpose the file cfitsio3260.tar.gz needs to be present in
the subdirectory libcfitsio/. It can be obtained from
http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio3260.tar.gz
Please simply put the .tar.gz file into the libcfitsio/ directory; it will
be unpacked and compiled automatically.
If you have a more recent version of the cfitsio package, please edit the
line starting with "PACKAGE =" in the file libcfitsio/planck.make accordingly.
GNU make is also required for compilation.
To compile the package, set the environment variable
HEALPIX_TARGET to the target for which you want to compile
(e.g. generic_gcc, linux_icc etc.). If a fairly recent version
(4.2 or higher) of gcc and g++ is installed on the system, the target
"generic_gcc" should work in most cases; however, for Mac OS X, "osx" is
recommended. For each possible target there exists a configuration file with
the name config.$HEALPIX_TARGET in the directory config/.
Afterwards, just type "gmake" or "make".
If the compilers on your platform have different names or you
want to make other changes, editing the configuration files
should be quite straightforward.
Please note that all temporary and object files are created
separately from the source files in a directory called
"build.$HEALPIX_TARGET". This allows simultaneous compilation
for different platforms.
Documentation can be created by the command "(g)make doc".
However this requires the doxygen application to be installed
on your system.
The documentation will be created in the subdirectory doc/.

83
external/healpix/c_utils/c_utils.c vendored Normal file
View file

@ -0,0 +1,83 @@
/*
* This file is part of libc_utils.
*
* libc_utils 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.
*
* libc_utils is distributed in the hope that 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 libc_utils; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libc_utils is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Convenience functions
*
* Copyright (C) 2008, 2009, 2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include <stdio.h>
#include <stdlib.h>
#include "c_utils.h"
void util_fail_ (const char *file, int line, const char *func, const char *msg)
{
fprintf(stderr,"%s, %i (%s):\n%s\n",file,line,func,msg);
exit(1);
}
void util_warn_ (const char *file, int line, const char *func, const char *msg)
{
fprintf(stderr,"%s, %i (%s):\n%s\n",file,line,func,msg);
exit(1);
}
/* This function tries to avoid allocations with a total size close to a high
power of two (called the "critical stride" here), by adding a few more bytes
if necssary. This lowers the probability that two arrays differ by a multiple
of the critical stride in their starting address, which in turn lowers the
risk of cache line contention. */
static size_t manipsize(size_t sz)
{
const size_t critical_stride=4096, cacheline=64, overhead=32;
if (sz < (critical_stride/2)) return sz;
if (((sz+overhead)%critical_stride)>(2*cacheline)) return sz;
return sz+2*cacheline;
}
#ifdef __SSE__
#include <xmmintrin.h>
void *util_malloc_ (size_t sz)
{
void *res;
if (sz==0) return NULL;
res = _mm_malloc(manipsize(sz),16);
UTIL_ASSERT(res,"_mm_malloc() failed");
return res;
}
void util_free_ (void *ptr)
{ if ((ptr)!=NULL) _mm_free(ptr); }
#else
void *util_malloc_ (size_t sz)
{
void *res;
if (sz==0) return NULL;
res = malloc(manipsize(sz));
UTIL_ASSERT(res,"malloc() failed");
return res;
}
void util_free_ (void *ptr)
{ if ((ptr)!=NULL) free(ptr); }
#endif

125
external/healpix/c_utils/c_utils.h vendored Normal file
View file

@ -0,0 +1,125 @@
/*
* This file is part of libc_utils.
*
* libc_utils 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.
*
* libc_utils is distributed in the hope that 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 libc_utils; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libc_utils is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file c_utils.h
* Convenience functions
*
* Copyright (C) 2008, 2009, 2010 Max-Planck-Society
* \author Martin Reinecke
* \note This file should only be included from .c files, NOT from .h files.
*/
#ifndef PLANCK_C_UTILS_H
#define PLANCK_C_UTILS_H
#include <math.h>
#include <stdlib.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void util_fail_ (const char *file, int line, const char *func, const char *msg);
void util_warn_ (const char *file, int line, const char *func, const char *msg);
void *util_malloc_ (size_t sz);
void util_free_ (void *ptr);
#if defined (__GNUC__)
#define UTIL_FUNC_NAME__ __func__
#else
#define UTIL_FUNC_NAME__ "unknown"
#endif
#define UTIL_ASSERT(cond,msg) \
if(!(cond)) util_fail_(__FILE__,__LINE__,UTIL_FUNC_NAME__,msg)
#define UTIL_WARN(cond,msg) \
if(!(cond)) util_warn_(__FILE__,__LINE__,UTIL_FUNC_NAME__,msg)
#define UTIL_FAIL(msg) \
util_fail_(__FILE__,__LINE__,UTIL_FUNC_NAME__,msg)
#define ALLOC(ptr,type,num) \
do { (ptr)=(type *)util_malloc_((num)*sizeof(type)); } while (0)
#define RALLOC(type,num) \
((type *)util_malloc_((num)*sizeof(type)))
#define DEALLOC(ptr) \
do { util_free_(ptr); (ptr)=NULL; } while(0)
#define RESIZE(ptr,type,num) \
do { util_free_(ptr); ALLOC(ptr,type,num); } while(0)
#define REALLOC(ptr,type,num) \
do { \
ptr = (type *)realloc(ptr,(num)*sizeof(type)); \
UTIL_ASSERT(ptr,"realloc() failed"); \
} while(0)
#define GROW(ptr,type,sz_old,sz_new) \
do { \
if ((sz_new)>(sz_old)) \
{ RESIZE(ptr,type,2*(sz_new));sz_old=2*(sz_new); } \
} while(0)
#define SET_ARRAY(ptr,i1,i2,val) \
do { \
ptrdiff_t cnt_; \
for (cnt_=(i1);cnt_<(i2);++cnt_) (ptr)[cnt_]=(val); \
} while(0)
#define COPY_ARRAY(src,dest,i1,i2) \
do { \
ptrdiff_t cnt_; \
for (cnt_=(i1);cnt_<(i2);++cnt_) (dest)[cnt_]=(src)[cnt_]; \
} while(0)
#define ALLOC2D(ptr,type,num1,num2) \
do { \
size_t cnt_, num1_=(num1), num2_=(num2); \
ALLOC(ptr,type *,num1_); \
ALLOC(ptr[0],type,num1_*num2_); \
for (cnt_=1; cnt_<num1_; ++cnt_) \
ptr[cnt_]=ptr[cnt_-1]+num2_; \
} while(0)
#define DEALLOC2D(ptr) \
do { if(ptr) DEALLOC((ptr)[0]); DEALLOC(ptr); } while(0)
#define FAPPROX(a,b,eps) \
(fabs((a)-(b))<((eps)*fabs(b)))
#define ABSAPPROX(a,b,eps) \
(fabs((a)-(b))<(eps))
#define IMAX(a,b) \
(((a)>(b)) ? (a) : (b))
#define IMIN(a,b) \
(((a)<(b)) ? (a) : (b))
#define SWAP(a,b,type) \
do { type tmp_=(a); (a)=(b); (b)=tmp_; } while(0)
#define CHECK_STACK_ALIGN(align) \
do { \
double foo; \
UTIL_WARN((((size_t)(&foo))&(align-1))==0, \
"WARNING: stack not sufficiently aligned!"); \
} while(0)
#ifdef __cplusplus
}
#endif
#endif

18
external/healpix/c_utils/planck.make vendored Normal file
View file

@ -0,0 +1,18 @@
PKG:=c_utils
SD:=$(SRCROOT)/$(PKG)
OD:=$(BLDROOT)/$(PKG)
FULL_INCLUDE+= -I$(SD)
HDR_$(PKG):=$(SD)/*.h
LIB_$(PKG):=$(LIBDIR)/libc_utils.a
OBJ:=c_utils.o walltime_c.o
OBJ:=$(OBJ:%=$(OD)/%)
$(OBJ): $(HDR_$(PKG)) | $(OD)_mkdir
$(LIB_$(PKG)): $(OBJ)
all_hdr+=$(HDR_$(PKG))
all_lib+=$(LIB_$(PKG))

137
external/healpix/c_utils/sse_utils.h vendored Normal file
View file

@ -0,0 +1,137 @@
/*
* This file is part of libc_utils.
*
* libc_utils 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.
*
* libc_utils is distributed in the hope that 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 libc_utils; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libc_utils is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file sse_utils.h
* SSE/SSE2/SSE3-related functionality
*
* Copyright (C) 2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_SSE_UTILS_H
#define PLANCK_SSE_UTILS_H
#ifndef PLANCK_DISABLE_SSE
#if (defined(__SSE__))
#include <xmmintrin.h>
#define PLANCK_HAVE_SSE
#ifdef __cplusplus
extern "C" {
#endif
typedef __m128 v4sf; /* vector of 4 floats (SSE1) */
typedef union {
float f[4];
v4sf v;
} V4SF;
static inline v4sf build_v4sf (float a, float b, float c, float d)
{ return _mm_set_ps(d,c,b,a); }
static inline void read_v4sf (v4sf v, float *a, float *b, float *c, float *d)
{
V4SF tmp;
tmp.v = v;
if (a) *a=tmp.f[0];
if (b) *b=tmp.f[1];
if (c) *c=tmp.f[2];
if (d) *d=tmp.f[3];
}
#ifdef __cplusplus
}
#endif
#endif
#if (defined(__SSE2__))
#include <emmintrin.h>
#define PLANCK_HAVE_SSE2
#ifdef __cplusplus
extern "C" {
#endif
typedef __m128d v2df; /* vector of 2 doubles (SSE2) */
typedef union {
double d[2];
v2df v;
} V2DF;
typedef struct {
v2df a,b;
} v2df2;
typedef struct {
V2DF a,b;
} V2DF2;
#define V2DF_SIGNMASK \
_mm_castsi128_pd(_mm_set_epi32(-0x80000000,0,-0x80000000,0))
static inline v2df build_v2df (double a, double b)
{ return _mm_set_pd(b,a); }
static inline void read_v2df (v2df v, double *a, double *b)
{ _mm_store_sd(a,v); _mm_storeh_pd(b,v); }
static inline int v2df_any_gt (v2df a, v2df b)
{
return (_mm_movemask_pd(_mm_cmpgt_pd(_mm_andnot_pd(V2DF_SIGNMASK,a),b))!=0);
}
static inline int v2df_all_ge (v2df a, v2df b)
{
return (_mm_movemask_pd(_mm_cmplt_pd(_mm_andnot_pd(V2DF_SIGNMASK,a),b))==0);
}
static inline V2DF to_V2DF (v2df x)
{ V2DF X; X.v=x; return X; }
static inline V2DF2 to_V2DF2 (v2df2 x)
{ V2DF2 X; X.a.v=x.a; X.b.v=x.b; return X; }
static inline v2df2 to_v2df2 (V2DF2 X)
{ v2df2 x; x.a=X.a.v; x.b=X.b.v; return x; }
static inline v2df2 zero_v2df2(void)
{ v2df2 x; x.a=x.b=_mm_setzero_pd(); return x; }
#ifdef __cplusplus
}
#endif
#endif
#if (defined(__SSE3__))
#include <pmmintrin.h>
#define PLANCK_HAVE_SSE3
#endif
#endif
#endif

78
external/healpix/c_utils/walltime_c.c vendored Normal file
View file

@ -0,0 +1,78 @@
/*
* This file is part of libc_utils.
*
* libc_utils 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.
*
* libc_utils is distributed in the hope that 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 libc_utils; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libc_utils is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Functionality for reading wall clock time
*
* Copyright (C) 2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#if defined (_OPENMP)
#include <omp.h>
#elif defined (USE_MPI)
#include "mpi.h"
#else
#include <sys/time.h>
#include <stdlib.h>
#endif
#include "walltime_c.h"
double wallTime(void)
{
#if defined (_OPENMP)
return omp_get_wtime();
#elif defined (USE_MPI)
return MPI_Wtime();
#else
struct timeval t;
gettimeofday(&t, NULL);
return t.tv_sec + 1e-6*t.tv_usec;
#endif
}
typedef struct
{
double ts,ta;
int on;
} wTimer;
#define NTIMERS 100
static wTimer wT[NTIMERS];
int wTimer_num(void)
{ return NTIMERS; }
void wTimer_reset(int n)
{ wT[n].ts=wT[n].ta=wT[n].on=0; }
void wTimer_start(int n)
{ wT[n].ts=wallTime(); wT[n].on=1; }
void wTimer_stop(int n)
{
if (wT[n].on)
{ wT[n].ta+=wallTime()-wT[n].ts; wT[n].on=0; }
}
double wTimer_acc(int n)
{ return wT[n].on ? wT[n].ta+wallTime()-wT[n].ts : wT[n].ta; }

59
external/healpix/c_utils/walltime_c.h vendored Normal file
View file

@ -0,0 +1,59 @@
/*
* This file is part of libc_utils.
*
* libc_utils 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.
*
* libc_utils is distributed in the hope that 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 libc_utils; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libc_utils is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file walltime_c.h
* Functionality for reading wall clock time
*
* Copyright (C) 2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_WALLTIME_C_H
#define PLANCK_WALLTIME_C_H
#ifdef __cplusplus
extern "C" {
#endif
/*! Returns an approximation of the current wall time (in seconds).
The first available of the following timers will be used:
<ul>
<li> \a omp_get_wtime(), if OpenMP is available
<li> \a MPI_Wtime(), if MPI is available
<li> \a gettimeofday() otherwise
</li>
\note Only useful for measuring time differences. */
double wallTime(void);
int wTimer_num(void);
void wTimer_reset(int n);
void wTimer_start(int n);
void wTimer_stop(int n);
double wTimer_acc(int n);
#ifdef __cplusplus
}
#endif
#endif

33
external/healpix/config/config.sampler vendored Normal file
View file

@ -0,0 +1,33 @@
LS_OPTFLAGS:= -O2 -ffast-math -fomit-frame-pointer $(EXTRA_CPPFLAGS) $(HEALPIX_EXTRAFLAGS)
LS_DEBUGFLAGS:= #-g
ifeq ($(strip $(OMP_SUPPORT)),ON)
LS_OMPFLAGS= $(OMP_FLAGS)
else
LS_OMPFLAGS= -U_OPENMP
endif
LS_PROFILEFLAGS:= #-pg
LS_STATICFLAGS:= #-static
LS_PICFLAGS:= -fPIC
EXTERNAL_CFITSIO= yes
CFITSIO_EXT_PREFIX= ${HEALPIX_BASE_PATH}/ext_build/cfitsio
CFITSIO_EXT_LIB= ${CFITSIO_EXT_PREFIX}/lib/libcfitsio.a
CFITSIO_EXT_INC= ${CFITSIO_EXT_PREFIX}/include/
CC= $(HEALPIX_CC)
CL= $(HEALPIX_CC)
CWARNFLAGS= -Wall -Wextra -Wno-long-long -Wno-unknown-pragmas -Wshadow -Wmissing-prototypes -Wfatal-errors
CCFLAGS_NO_C= $(CWARNFLAGS) $(LS_PROFILEFLAGS) $(LS_DEBUGFLAGS) $(LS_OMPFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS) -fno-strict-aliasing --std=gnu89 -pedantic -fdata-sections -ffunction-sections
CCFLAGS= $(CCFLAGS_NO_C) -c
CLFLAGS= -L. -L$(LIBDIR) $(LS_PROFILEFLAGS) $(LS_OMPFLAGS) $(LS_STATICFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS) -lm
CXX= $(HEALPIX_CXX)
CXXL= $(HEALPIX_CXX)
CXXWARNFLAGS= -Wall -Wextra -Wstrict-aliasing=2 -Wundef -Wshadow -Wwrite-strings -Wredundant-decls -Woverloaded-virtual -Wcast-qual -Wcast-align -Wpointer-arith -Wold-style-cast -Wno-unknown-pragmas -Wfatal-errors
CXXCFLAGS_NO_C= $(CXXWARNFLAGS) $(LS_PROFILEFLAGS) $(LS_DEBUGFLAGS) $(LS_OMPFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS) -ansi -fdata-sections -ffunction-sections
CXXCFLAGS= $(CXXCFLAGS_NO_C) -c
CXXLFLAGS= -L. -L$(LIBDIR) $(LS_PROFILEFLAGS) $(LS_OMPFLAGS) $(LS_STATICFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS)
ARCREATE= ar cr

View file

@ -0,0 +1,27 @@
LS_OPTFLAGS:= -O2 -ffast-math -fomit-frame-pointer $(HEALPIX_EXTRAFLAGS)
LS_DEBUGFLAGS:= #-g
LS_OMPFLAGS:= #-fopenmp
LS_PROFILEFLAGS:= #-pg
LS_STATICFLAGS:= #-static
LS_PICFLAGS:= -fPIC
EXTERNAL_CFITSIO= yes
CFITSIO_EXT_PREFIX= ${HEALPIX_BASE_PATH}/../cfitsio
CFITSIO_EXT_LIB= ${CFITSIO_EXT_PREFIX}/libcfitsio.a
CFITSIO_EXT_INC= ${CFITSIO_EXT_PREFIX}
CC= gcc
CL= gcc
CWARNFLAGS= -Wall -Wextra -Wno-long-long -Wno-unknown-pragmas -Wshadow -Wmissing-prototypes -Wfatal-errors
CCFLAGS_NO_C= $(CWARNFLAGS) $(LS_PROFILEFLAGS) $(LS_DEBUGFLAGS) $(LS_OMPFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS) -fno-strict-aliasing --std=gnu89 -pedantic -fdata-sections -ffunction-sections
CCFLAGS= $(CCFLAGS_NO_C) -c
CLFLAGS= -L. -L$(LIBDIR) $(LS_PROFILEFLAGS) $(LS_OMPFLAGS) $(LS_STATICFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS) -lm
CXX= g++
CXXL= g++
CXXWARNFLAGS= -Wall -Wextra -Wstrict-aliasing=2 -Wundef -Wshadow -Wwrite-strings -Wredundant-decls -Woverloaded-virtual -Wcast-qual -Wcast-align -Wpointer-arith -Wold-style-cast -Wno-unknown-pragmas -Wfatal-errors
CXXCFLAGS_NO_C= $(CXXWARNFLAGS) $(LS_PROFILEFLAGS) $(LS_DEBUGFLAGS) $(LS_OMPFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS) -ansi -fdata-sections -ffunction-sections
CXXCFLAGS= $(CXXCFLAGS_NO_C) -c
CXXLFLAGS= -L. -L$(LIBDIR) $(LS_PROFILEFLAGS) $(LS_OMPFLAGS) $(LS_STATICFLAGS) $(LS_PICFLAGS) $(LS_OPTFLAGS)
ARCREATE= libtool -static -o

25
external/healpix/config/rules.common vendored Normal file
View file

@ -0,0 +1,25 @@
BLDROOT = $(SRCROOT)/build.$(HEALPIX_TARGET)
PREFIX = $(SRCROOT)/$(HEALPIX_TARGET)
BINDIR = $(PREFIX)/bin
INCDIR = $(PREFIX)/include
LIBDIR = $(PREFIX)/lib
DOCDIR = $(SRCROOT)/doc
# do not use any suffix rules
.SUFFIXES:
# do not use any default rules
.DEFAULT:
$(BLDROOT)/%.o : $(SRCROOT)/%.c
@echo "# compiling $*.c"
cd $(@D) && $(CC) $(FULL_INCLUDE) -I$(BLDROOT) $(CCFLAGS) $<
$(BLDROOT)/%.o : $(SRCROOT)/%.cc
@echo "# compiling $*.cc"
cd $(@D) && $(CXX) $(FULL_INCLUDE) -I$(BLDROOT) $(CXXCFLAGS) $<
%_mkdir:
@if [ ! -d $* ]; then mkdir -p $* ; fi
distclean: docsrc_clean
rm -rf $(BLDROOT) $(PREFIX) $(DOCDIR) $(SRCROOT)/test/test*

632
external/healpix/cxxsupport/arr.h vendored Normal file
View file

@ -0,0 +1,632 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file arr.h
* Various high-performance array classes used by the Planck LevelS package.
*
* Copyright (C) 2002 - 2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_ARR_H
#define PLANCK_ARR_H
#include <algorithm>
#include <cstdlib>
#include "cxxutils.h"
/*! \defgroup arraygroup Array classes */
/*! \{ */
template <typename T> class normalAlloc__
{
public:
T *alloc(tsize sz) const { return (sz>0) ? new T[sz] : 0; }
void dealloc (T *ptr) const { delete[] ptr; }
};
template <typename T, int align> class alignAlloc__
{
public:
T *alloc(tsize sz) const
{
using namespace std;
if (sz==0) return 0;
void *res;
planck_assert(posix_memalign(&res,align,sz*sizeof(T))==0,
"error in posix_memalign()");
return static_cast<T *>(res);
}
void dealloc(T *ptr) const
{
using namespace std;
if (ptr) free(ptr);
}
};
/*! View of a 1D array */
template <typename T> class arr_ref
{
protected:
tsize s;
T *d;
public:
/*! Constructs an \a arr_ref of size \a s_, starting at \a d_. */
arr_ref(T *d_, tsize s_) : s(s_),d(d_) {}
/*! Returns the current array size. */
tsize size() const { return s; }
/*! Writes \a val into every element of the array. */
void fill (const T &val)
{ for (tsize m=0; m<s; ++m) d[m]=val; }
/*! Returns a reference to element \a n */
template<typename T2> T &operator[] (T2 n) {return d[n];}
/*! Returns a constant reference to element \a n */
template<typename T2> const T &operator[] (T2 n) const {return d[n];}
/*! Returns a pointer to the first array element, or NULL if the array
is zero-sized. */
T *begin() { return d; }
/*! Returns a pointer to the one-past-last array element, or NULL if the
array is zero-sized. */
T *end() { return d+s; }
/*! Returns a constant pointer to the first array element, or NULL if the
array is zero-sized. */
const T *begin() const { return d; }
/*! Returns a constant pointer to the one-past-last array element, or NULL
if the array is zero-sized. */
const T *end() const { return d+s; }
/*! Copies all array elements to \a ptr. */
template<typename T2> void copyToPtr (T *ptr) const
{ for (tsize m=0; m<s; ++m) ptr[m]=d[m]; }
/*! Sorts the elements in the array, in ascending order. */
void sort()
{ std::sort (d,d+s); }
/*! Sorts the elements in the array, such that \a comp(d[i],d[j])==true
for \a i<j. */
template<typename Comp> void sort(Comp comp)
{ std::sort (d,d+s,comp); }
/*! Helper function for linear interpolation (or extrapolation).
\a idx and \a val are computed such that
\a val=d[idx]+frac*(d[idx+1]-d[idx]). If \a val<d[0], \a frac will be
negative, if \a val>d[s-1], frac will be larger than 1. In all other
cases \a 0<=frac<=1.
The array must be ordered in ascending order; no two values may be
equal. */
void interpol_helper (const T &val, tsize &idx, double &frac) const
{ ::interpol_helper (d, d+s, val, idx, frac); }
/*! Helper function for linear interpolation (or extrapolation).
\a idx and \a val are computed such that
\a val=d[idx]+frac*(d[idx+1]-d[idx]). If \a comp(val,d[0])==true,
\a frac will be negative, if \a comp(val,d[s-1])==false, frac will be
larger than 1. In all other cases \a 0<=frac<=1.
The array must be ordered such that \a comp(d[i],d[j])==true
for \a i<j; no two values may be equal. */
template<typename Comp> void interpol_helper (const T &val, Comp comp,
tsize &idx, double &frac) const
{ ::interpol_helper (d, d+s, val, comp, idx, frac); }
/*! Returns the minimum and maximum entry in \a minv and \a maxv,
respectively. Throws an exception if the array is zero-sized. */
void minmax (T &minv, T &maxv) const
{
planck_assert(s>0,"trying to find min and max of a zero-sized array");
minv=maxv=d[0];
for (tsize m=1; m<s; ++m)
{
if (d[m]<minv) minv=d[m];
else if (d[m]>maxv) maxv=d[m];
}
}
/*! Returns \a true, if \a val is found in the array, else \a false. */
bool contains (const T &val) const
{
for (tsize m=0; m<s; ++m)
if (d[m]==val) return true;
return false;
}
/*! Returns the index of the first occurrence of \a val in the array.
If it is not found, an exception is thrown. */
tsize find (const T &val) const
{
for (tsize m=0; m<s; ++m)
if (d[m]==val) return m;
planck_fail ("entry '"+dataToString(val)+"' not found in array");
}
};
/*! An array whose size is known at compile time. Very useful for storing
small arrays on the stack, without need for \a new and \a delete(). */
template <typename T, tsize sz> class fix_arr
{
private:
T d[sz];
public:
/*! Returns the size of the array. */
tsize size() const { return sz; }
/*! Returns a reference to element \a n */
template<typename T2> T &operator[] (T2 n) {return d[n];}
/*! Returns a constant reference to element \a n */
template<typename T2> const T &operator[] (T2 n) const {return d[n];}
};
/*! One-dimensional array type, with selectable storage management. */
template <typename T, typename storageManager> class arrT: public arr_ref<T>
{
private:
storageManager stm;
bool own;
void reset()
{ this->d=0; this->s=0; own=true; }
public:
/*! Creates a zero-sized array. */
arrT() : arr_ref<T>(0,0), own(true) {}
/*! Creates an array with \a sz entries. */
arrT(tsize sz) : arr_ref<T>(stm.alloc(sz),sz), own(true) {}
/*! Creates an array with \a sz entries, and initializes them with
\a inival. */
arrT(tsize sz, const T &inival) : arr_ref<T>(stm.alloc(sz),sz), own(true)
{ arr_ref<T>::fill(inival); }
/*! Creates an array with \a sz entries, which uses the memory pointed
to by \a ptr.
\note \a ptr will <i>not</i> be deallocated by the destructor.
\warning Only use this if you REALLY know what you are doing.
In particular, this is only safely usable if
<ul>
<li>\a T is a POD type</li>
<li>\a ptr survives during the lifetime of the array object</li>
<li>\a ptr is not subject to garbage collection</li>
</ul>
Other restrictions may apply. You have been warned. */
arrT (T *ptr, tsize sz): arr_ref<T>(ptr,sz), own(false) {}
/*! Creates an array which is a copy of \a orig. The data in \a orig
is duplicated. */
arrT (const arrT &orig): arr_ref<T>(stm.alloc(orig.s),orig.s), own(true)
{ for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m]; }
/*! Frees the memory allocated by the object. */
~arrT() { if (own) stm.dealloc(this->d); }
/*! Allocates space for \a sz elements. The content of the array is
undefined on exit. \a sz can be 0. If \a sz is the
same as the current size, no reallocation is performed. */
void alloc (tsize sz)
{
if (sz==this->s) return;
if (own) stm.dealloc(this->d);
this->s = sz;
this->d = stm.alloc(sz);
own = true;
}
/*! Allocates space for \a sz elements. If \a sz is the
same as the current size, no reallocation is performed.
All elements are set to \a inival. */
void allocAndFill (tsize sz, const T &inival)
{ alloc(sz); this->fill(inival); }
/*! Deallocates the memory held by the array, and sets the array size
to 0. */
void dealloc() {if (own) stm.dealloc(this->d); reset();}
/*! Changes the array to be a copy of \a orig. */
arrT &operator= (const arrT &orig)
{
if (this==&orig) return *this;
alloc (orig.s);
for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m];
return *this;
}
/*! Reserves space for \a sz elements, then copies \a sz elements
from \a ptr into the array. */
template<typename T2> void copyFromPtr (const T2 *ptr, tsize sz)
{
alloc(sz);
for (tsize m=0; m<this->s; ++m) this->d[m]=ptr[m];
}
/*! Assigns the contents and size of \a other to the array.
\note On exit, \a other is zero-sized! */
void transfer (arrT &other)
{
if (own) stm.dealloc(this->d);
this->d=other.d;
this->s=other.s;
own=other.own;
other.reset();
}
/*! Swaps contents and size with \a other. */
void swap (arrT &other)
{
std::swap(this->d,other.d);
std::swap(this->s,other.s);
std::swap(own,other.own);
}
};
/*! One-dimensional array type. */
template <typename T>
class arr: public arrT<T,normalAlloc__<T> >
{
public:
/*! Creates a zero-sized array. */
arr() : arrT<T,normalAlloc__<T> >() {}
/*! Creates an array with \a sz entries. */
arr(tsize sz) : arrT<T,normalAlloc__<T> >(sz) {}
/*! Creates an array with \a sz entries, and initializes them with
\a inival. */
arr(tsize sz, const T &inival) : arrT<T,normalAlloc__<T> >(sz,inival) {}
/*! Creates an array with \a sz entries, which uses the memory pointed
to by \a ptr.
\note \a ptr will <i>not</i> be deallocated by the destructor.
\warning Only use this if you REALLY know what you are doing.
In particular, this is only safely usable if
<ul>
<li>\a T is a POD type</li>
<li>\a ptr survives during the lifetime of the array object</li>
<li>\a ptr is not subject to garbage collection</li>
</ul>
Other restrictions may apply. You have been warned. */
arr (T *ptr, tsize sz): arrT<T,normalAlloc__<T> >(ptr,sz) {}
};
/*! One-dimensional array type, with selectable storage alignment. */
template <typename T, int align>
class arr_align: public arrT<T,alignAlloc__<T,align> >
{
public:
/*! Creates a zero-sized array. */
arr_align() : arrT<T,alignAlloc__<T,align> >() {}
/*! Creates an array with \a sz entries. */
arr_align(tsize sz) : arrT<T,alignAlloc__<T,align> >(sz) {}
/*! Creates an array with \a sz entries, and initializes them with
\a inival. */
arr_align(tsize sz, const T &inival)
: arrT<T,alignAlloc__<T,align> >(sz,inival) {}
};
/*! Two-dimensional array type, with selectable storage management.
The storage ordering is the same as in C.
An entry is located by address arithmetic, not by double dereferencing.
The indices start at zero. */
template <typename T, typename storageManager> class arr2T
{
private:
tsize s1, s2;
arrT<T, storageManager> d;
public:
/*! Creates a zero-sized array. */
arr2T() : s1(0), s2(0) {}
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
arr2T(tsize sz1, tsize sz2)
: s1(sz1), s2(sz2), d(s1*s2) {}
/*! Creates an array with the dimensions \a sz1 and \a sz2
and initializes them with \a inival. */
arr2T(tsize sz1, tsize sz2, const T &inival)
: s1(sz1), s2(sz2), d (s1*s2)
{ fill(inival); }
/*! Creates the array as a copy of \a orig. */
arr2T(const arr2T &orig)
: s1(orig.s1), s2(orig.s2), d(orig.d) {}
/*! Frees the memory associated with the array. */
~arr2T() {}
/*! Returns the first array dimension. */
tsize size1() const { return s1; }
/*! Returns the second array dimension. */
tsize size2() const { return s2; }
/*! Returns the total array size, i.e. the product of both dimensions. */
tsize size () const { return s1*s2; }
/*! Allocates space for an array with \a sz1*sz2 elements.
The content of the array is undefined on exit.
\a sz1 or \a sz2 can be 0. If \a sz1*sz2 is the same as the
currently allocated space, no reallocation is performed. */
void alloc (tsize sz1, tsize sz2)
{
if (sz1*sz2 != d.size())
d.alloc(sz1*sz2);
s1=sz1; s2=sz2;
}
/*! Allocates space for an array with \a sz1*sz2 elements.
All elements are set to \a inival.
\a sz1 or \a sz2 can be 0. If \a sz1*sz2 is the same as the
currently allocated space, no reallocation is performed. */
void allocAndFill (tsize sz1, tsize sz2, const T &inival)
{ alloc(sz1,sz2); fill(inival); }
/*! Allocates space for an array with \a sz1*sz2 elements.
The content of the array is undefined on exit.
\a sz1 or \a sz2 can be 0. If \a sz1*sz2 is smaller than the
currently allocated space, no reallocation is performed. */
void fast_alloc (tsize sz1, tsize sz2)
{
if (sz1*sz2<=d.size())
{ s1=sz1; s2=sz2; }
else
alloc(sz1,sz2);
}
/*! Deallocates the space and makes the array zero-sized. */
void dealloc () {d.dealloc(); s1=0; s2=0;}
/*! Sets all array elements to \a val. */
void fill (const T &val)
{ for (tsize m=0; m<s1*s2; ++m) d[m]=val; }
/*! Changes the array to be a copy of \a orig. */
arr2T &operator= (const arr2T &orig)
{
if (this==&orig) return *this;
alloc (orig.s1, orig.s2);
d = orig.d;
return *this;
}
/*! Returns a pointer to the beginning of slice \a n. */
template<typename T2> T *operator[] (T2 n) {return &d[n*s2];}
/*! Returns a constant pointer to the beginning of slice \a n. */
template<typename T2> const T *operator[] (T2 n) const {return &d[n*s2];}
/*! Returns a reference to the element with the indices \a n1 and \a n2. */
template<typename T2, typename T3> T &operator() (T2 n1, T3 n2)
{return d[n1*s2 + n2];}
/*! Returns a constant reference to the element with the indices
\a n1 and \a n2. */
template<typename T2, typename T3> const T &operator() (T2 n1, T3 n2) const
{return d[n1*s2 + n2];}
/*! Returns the minimum and maximum entry in \a minv and \a maxv,
respectively. Throws an exception if the array is zero-sized. */
void minmax (T &minv, T &maxv) const
{
planck_assert(s1*s2>0,
"trying to find min and max of a zero-sized array");
minv=maxv=d[0];
for (tsize m=1; m<s1*s2; ++m)
{
if (d[m]<minv) minv=d[m];
if (d[m]>maxv) maxv=d[m];
}
}
/*! Swaps contents and sizes with \a other. */
void swap (arr2T &other)
{
d.swap(other.d);
std::swap(s1,other.s1);
std::swap(s2,other.s2);
}
/*! Returns \c true if the array and \a other have the same dimensions,
else \c false. */
template<typename T2, typename T3> bool conformable
(const arr2T<T2,T3> &other) const
{ return (other.size1()==s1) && (other.size2()==s2); }
};
/*! Two-dimensional array type. The storage ordering is the same as in C.
An entry is located by address arithmetic, not by double dereferencing.
The indices start at zero. */
template <typename T>
class arr2: public arr2T<T,normalAlloc__<T> >
{
public:
/*! Creates a zero-sized array. */
arr2() : arr2T<T,normalAlloc__<T> > () {}
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
arr2(tsize sz1, tsize sz2) : arr2T<T,normalAlloc__<T> > (sz1,sz2) {}
/*! Creates an array with the dimensions \a sz1 and \a sz2
and initializes them with \a inival. */
arr2(tsize sz1, tsize sz2, const T &inival)
: arr2T<T,normalAlloc__<T> > (sz1,sz2,inival) {}
};
/*! Two-dimensional array type, with selectable storage alignment.
The storage ordering is the same as in C.
An entry is located by address arithmetic, not by double dereferencing.
The indices start at zero. */
template <typename T, int align>
class arr2_align: public arr2T<T,alignAlloc__<T,align> >
{
public:
/*! Creates a zero-sized array. */
arr2_align() : arr2T<T,alignAlloc__<T,align> > () {}
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
arr2_align(tsize sz1, tsize sz2)
: arr2T<T,alignAlloc__<T,align> > (sz1,sz2) {}
/*! Creates an array with the dimensions \a sz1 and \a sz2
and initializes them with \a inival. */
arr2_align(tsize sz1, tsize sz2, const T &inival)
: arr2T<T,alignAlloc__<T,align> > (sz1,sz2,inival) {}
};
/*! Two-dimensional array type. An entry is located by double dereferencing,
i.e. via an array of pointers. The indices start at zero. */
template <typename T> class arr2b
{
private:
tsize s1, s2;
arr<T> d;
arr<T *> d1;
void fill_d1()
{ for (tsize m=0; m<s1; ++m) d1[m] = &d[m*s2]; }
public:
/*! Creates a zero-sized array. */
arr2b() : s1(0), s2(0), d(0), d1(0) {}
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
arr2b(tsize sz1, tsize sz2)
: s1(sz1), s2(sz2), d(s1*s2), d1(s1)
{ fill_d1(); }
/*! Creates the array as a copy of \a orig. */
arr2b(const arr2b &orig)
: s1(orig.s1), s2(orig.s2), d(orig.d), d1(s1)
{ fill_d1(); }
/*! Frees the memory associated with the array. */
~arr2b() {}
/*! Returns the first array dimension. */
tsize size1() const { return s1; }
/*! Returns the second array dimension. */
tsize size2() const { return s2; }
/*! Returns the total array size, i.e. the product of both dimensions. */
tsize size () const { return s1*s2; }
/*! Allocates space for an array with \a sz1*sz2 elements.
The content of the array is undefined on exit. */
void alloc (tsize sz1, tsize sz2)
{
if ((s1==sz1) && (s2==sz2)) return;
s1=sz1; s2=sz2;
d.alloc(s1*s2);
d1.alloc(s1);
fill_d1();
}
/*! Deallocates the space and makes the array zero-sized. */
void dealloc () {d.dealloc(); d1.dealloc(); s1=0; s2=0;}
/*! Sets all array elements to \a val. */
void fill (const T &val)
{ d.fill(val); }
/*! Changes the array to be a copy of \a orig. */
arr2b &operator= (const arr2b &orig)
{
if (this==&orig) return *this;
alloc (orig.s1, orig.s2);
for (tsize m=0; m<s1*s2; ++m) d[m] = orig.d[m];
return *this;
}
/*! Returns a pointer to the beginning of slice \a n. */
template<typename T2> T *operator[] (T2 n) {return d1[n];}
/*! Returns a constant pointer to the beginning of slice \a n. */
template<typename T2> const T *operator[] (T2 n) const {return d1[n];}
/*! Returns a pointer to the beginning of the pointer array. */
T **p0() {return &d1[0];}
};
/*! Three-dimensional array type. The storage ordering is the same as in C.
An entry is located by address arithmetic, not by multiple dereferencing.
The indices start at zero. */
template <typename T> class arr3
{
private:
tsize s1, s2, s3, s2s3;
arr<T> d;
public:
/*! Creates a zero-sized array. */
arr3() : s1(0), s2(0), s3(0), s2s3(0), d(0) {}
/*! Creates an array with the dimensions \a sz1, \a sz2 and \a sz3. */
arr3(tsize sz1, tsize sz2, tsize sz3)
: s1(sz1), s2(sz2), s3(sz3), s2s3(s2*s3), d(s1*s2*s3) {}
/*! Creates the array as a copy of \a orig. */
arr3(const arr3 &orig)
: s1(orig.s1), s2(orig.s2), s3(orig.s3), s2s3(orig.s2s3), d(orig.d) {}
/*! Frees the memory associated with the array. */
~arr3() {}
/*! Returns the first array dimension. */
tsize size1() const { return s1; }
/*! Returns the second array dimension. */
tsize size2() const { return s2; }
/*! Returns the third array dimension. */
tsize size3() const { return s3; }
/*! Returns the total array size, i.e. the product of all dimensions. */
tsize size () const { return s1*s2*s3; }
/*! Allocates space for an array with \a sz1*sz2*sz3 elements.
The content of the array is undefined on exit. */
void alloc (tsize sz1, tsize sz2, tsize sz3)
{
d.alloc(sz1*sz2*sz3);
s1=sz1; s2=sz2; s3=sz3; s2s3=s2*s3;
}
/*! Deallocates the space and makes the array zero-sized. */
void dealloc () {d.dealloc(); s1=0; s2=0; s3=0; s2s3=0;}
/*! Sets all array elements to \a val. */
void fill (const T &val)
{ d.fill(val); }
/*! Changes the array to be a copy of \a orig. */
arr3 &operator= (const arr3 &orig)
{
if (this==&orig) return *this;
alloc (orig.s1, orig.s2, orig.s3);
d = orig.d;
return *this;
}
/*! Returns a reference to the element with the indices
\a n1, \a n2 and \a n3. */
template<typename T2, typename T3, typename T4> T &operator()
(T2 n1, T3 n2, T4 n3)
{return d[n1*s2s3 + n2*s3 + n3];}
/*! Returns a constant reference to the element with the indices
\a n1, \a n2 and \a n3. */
template<typename T2, typename T3, typename T4> const T &operator()
(T2 n1, T3 n2, T4 n3) const
{return d[n1*s2s3 + n2*s3 + n3];}
/*! Swaps contents and sizes with \a other. */
void swap (arr3 &other)
{
d.swap(other.d);
std::swap(s1,other.s1);
std::swap(s2,other.s2);
std::swap(s3,other.s3);
std::swap(s2s3,other.s2s3);
}
/*! Returns \c true if the array and \a other have the same dimensions,
else \c false. */
template<typename T2> bool conformable (const arr3<T2> &other) const
{ return (other.size1()==s1)&&(other.size2()==s2)&&(other.size3()==s3); }
};
/*! \} */
#endif

266
external/healpix/cxxsupport/bstream.h vendored Normal file
View file

@ -0,0 +1,266 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file bstream.h
* Classes for binary I/O with streams
*
* Copyright (C) 2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_BSTREAM_H
#define PLANCK_BSTREAM_H
#include <iostream>
#include <fstream>
#include <algorithm>
#include "datatypes.h"
/*! An object of this class can be cast to a \a bool, which indicates whether
the computer architecture is big-endian (true) or little-endian (false). */
class EndianTest__
{
private:
bool big_end;
public:
EndianTest__()
{
union { uint16 i16; uint8 i8; } tmp;
tmp.i16 = 1;
big_end = (tmp.i8==0);
}
operator bool() const { return big_end; }
};
const EndianTest__ big_endian;
template<size_t size> inline void byteswap_helper__ (char *);
template<> inline void byteswap_helper__<1> (char *)
{}
template<> inline void byteswap_helper__<2> (char *val)
{
using namespace std;
swap (val[0],val[1]);
}
template<> inline void byteswap_helper__<4> (char *val)
{
using namespace std;
swap (val[0],val[3]); swap (val[1],val[2]);
}
template<> inline void byteswap_helper__<8> (char *val)
{
using namespace std;
swap (val[0],val[7]); swap (val[1],val[6]);
swap (val[2],val[5]); swap (val[3],val[4]);
}
/*! Performs an endianness conversion on \a val.
\note \a T must be a primitive data type! */
template<typename T> inline void byteswap (T &val)
{ byteswap_helper__<sizeof(T)> (reinterpret_cast<char *> (&val)); }
const bool file_is_lsb=big_endian, file_is_msb=!big_endian,
file_is_natural=false;
/*! Class for writing binary data to a stream. */
class bostream
{
private:
std::ostream &s;
bool doswap;
public:
/*! Creates a new object which is attached to \a s_ and performs
endianness conversion if \a doswap_==true. */
bostream (std::ostream &s_, bool doswap_=false)
: s(s_), doswap(doswap_) {}
/*! Writes a binary representation of \a num objects of type \a T
(stored in \a data) to the attached stream. Endianness conversion
is performed if requested in the constructor.
\note \a T must be a primitive data type! */
template<typename T> bostream &put (const T *data, size_t num)
{
if ((sizeof(T)>1) && doswap)
for (size_t m=0; m<num; ++m)
{
T tmp=data[m];
byteswap (tmp);
s.write (reinterpret_cast<const char *> (&tmp), sizeof(T));
}
else
s.write (reinterpret_cast<const char *> (data), num*sizeof(T));
return *this;
}
/*! Writes a binary representation of \a data to the attached stream.
Endianness conversion is performed if requested in the constructor.
\note \a T must be a primitive data type! */
template<typename T> bostream &operator<< (const T &data)
{
put(&data,1);
return *this;
}
bool getSwap() const
{ return doswap; }
void setSwap(bool newswap)
{ doswap=newswap; }
void flipSwap()
{ doswap=!doswap; }
};
/*! Class for reading binary data from a stream. */
class bistream
{
private:
std::istream &s;
bool doswap;
public:
/*! Creates a new object which is attached to \a s_ and performs
endianness conversion if \a doswap_==true. */
bistream (std::istream &s_, bool doswap_=false)
: s(s_), doswap(doswap_) {}
/*! Reads a binary representation of \a num objects of type \a T
from the attached stream and stores them in \a data. Endianness
conversion is performed if requested in the constructor.
\note \a T must be a primitive data type! */
template<typename T> bistream &get (T *data, size_t num)
{
s.read (reinterpret_cast<char *> (data), num*sizeof(T));
if ((sizeof(T)>1) && doswap)
for (size_t m=0; m<num; ++m)
byteswap (data[m]);
return *this;
}
/*! Reads a binary representation of \a data from the attached stream.
Endianness conversion is performed if requested in the constructor.
\note \a T must be a primitive data type! */
template<typename T> bistream &operator>> (T &data)
{
get (&data,1);
return *this;
}
bool getSwap() const
{ return doswap; }
void setSwap(bool newswap)
{ doswap=newswap; }
void flipSwap()
{ doswap=!doswap; }
};
class bofstream: public std::ofstream
{
private:
bool doswap;
public:
/*! */
bofstream (const char *fname, bool doswap_)
: std::ofstream(fname,std::ios::binary), doswap(doswap_) {}
template<typename T> bofstream &operator<< (const T &data)
{
if (doswap)
{
T tmp = data;
byteswap (tmp);
write (reinterpret_cast<const char *> (&tmp), sizeof(T));
}
else
write (reinterpret_cast<const char *> (&data), sizeof(T));
return *this;
}
template<typename T> bofstream &put (const T *data, size_t num)
{
if (doswap)
for (size_t m=0; m<num; ++m)
{
T tmp=data[m];
byteswap (tmp);
write (reinterpret_cast<const char *> (&tmp), sizeof(T));
}
else
write (reinterpret_cast<const char *> (data), num*sizeof(T));
return *this;
}
bool getSwap() const
{ return doswap; }
void setSwap(bool newswap)
{ doswap=newswap; }
void flipSwap()
{ doswap=!doswap; }
};
class bifstream: public std::ifstream
{
private:
bool doswap;
public:
/*! */
bifstream ()
: doswap(false) {}
bifstream (const char *fname, bool doswap_)
: std::ifstream(fname,std::ios::binary), doswap(doswap_) {}
void open (const char *fname, bool doswap_)
{
doswap=doswap_;
std::ifstream::open(fname,std::ios::binary);
}
template<typename T> bifstream &operator>> (T &data)
{
read (reinterpret_cast<char *> (&data), sizeof(T));
if (doswap) byteswap (data);
return *this;
}
template<typename T> bifstream &get (T *data, size_t num)
{
read (reinterpret_cast<char *> (data), num*sizeof(T));
if (doswap)
for (size_t m=0; m<num; ++m)
byteswap (data[m]);
return *this;
}
void rewind()
{ seekg(0,std::ios::beg); }
void skip(std::streamoff nbytes)
{ seekg(nbytes,std::ios::cur); }
bool getSwap() const
{ return doswap; }
void setSwap(bool newswap)
{ doswap=newswap; }
void flipSwap()
{ doswap=!doswap; }
};
#endif

View file

@ -0,0 +1,4 @@
/*! \mainpage LevelS C++ support library documentation
Please refer to the <a href="modules.html">Modules</a> page for an overview
of the supplied functionality.
*/

304
external/healpix/cxxsupport/cxxutils.cc vendored Normal file
View file

@ -0,0 +1,304 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* This file contains the implementation of various convenience functions
* used by the Planck LevelS package.
*
* Copyright (C) 2002 - 2010 Max-Planck-Society
* Authors: Martin Reinecke, Reinhard Hell
*/
// if we are using g++, check for version 3.0 or higher
#ifdef __GNUC__
#if (__GNUC__<3)
#error your C++ compiler is too old. g++ version 3.0 or higher is required.
#endif
#endif
#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include "cxxutils.h"
#include "datatypes.h"
#include "openmp_support.h"
#include "sse_utils.h"
using namespace std;
string trim (const string &orig)
{
string::size_type p1=orig.find_first_not_of(" \t");
if (p1==string::npos) return "";
string::size_type p2=orig.find_last_not_of(" \t");
return orig.substr(p1,p2-p1+1);
}
template<typename T> string dataToString (const T &x)
{
ostringstream strstrm;
strstrm << x;
return trim(strstrm.str());
}
template<> string dataToString (const bool &x)
{ return x ? "T" : "F"; }
template<> string dataToString (const string &x)
{ return trim(x); }
template<> string dataToString (const float &x)
{
ostringstream strstrm;
strstrm << setprecision(8) << x;
return trim(strstrm.str());
}
template<> string dataToString (const double &x)
{
ostringstream strstrm;
strstrm << setprecision(16) << x;
return trim(strstrm.str());
}
template string dataToString (const signed char &x);
template string dataToString (const unsigned char &x);
template string dataToString (const short &x);
template string dataToString (const unsigned short &x);
template string dataToString (const int &x);
template string dataToString (const unsigned int &x);
template string dataToString (const long &x);
template string dataToString (const unsigned long &x);
template string dataToString (const long long &x);
template string dataToString (const unsigned long long &x);
string intToString(int64 x, tsize width)
{
ostringstream strstrm;
strstrm << setw(width) << setfill('0') << x;
return trim(strstrm.str());
}
namespace {
void end_stringToData (const string &x, const char *tn, istringstream &strstrm)
{
string error = string("conversion error in stringToData<")+tn+">(\""+x+"\")";
planck_assert (strstrm,error);
string rest;
strstrm >> rest;
// rest=trim(rest);
planck_assert (rest.length()==0,error);
}
} // unnamed namespace
template<typename T> void stringToData (const string &x, T &value)
{
istringstream strstrm(x);
strstrm >> value;
end_stringToData (x,type2typename<T>(),strstrm);
}
template<> void stringToData (const string &x, string &value)
{ value = trim(x); }
template<> void stringToData (const string &x, bool &value)
{
const char *x2 = x.c_str();
const char *fval[] = {"F","f","n","N","false",".false.","FALSE",".FALSE." };
const char *tval[] = {"T","t","y","Y","true",".true.","TRUE",".TRUE." };
for (tsize i=0; i< sizeof(fval)/sizeof(fval[0]); ++i)
if (strcmp(x2,fval[i])==0) { value=false; return; }
for (tsize i=0; i< sizeof(tval)/sizeof(tval[0]); ++i)
if (strcmp(x2,tval[i])==0) { value=true; return; }
planck_fail("conversion error in stringToData<bool>(\""+x+"\")");
}
template void stringToData (const string &x, signed char &value);
template void stringToData (const string &x, unsigned char &value);
template void stringToData (const string &x, short &value);
template void stringToData (const string &x, unsigned short &value);
template void stringToData (const string &x, int &value);
template void stringToData (const string &x, unsigned int &value);
template void stringToData (const string &x, long &value);
template void stringToData (const string &x, unsigned long &value);
template void stringToData (const string &x, long long &value);
template void stringToData (const string &x, unsigned long long &value);
template void stringToData (const string &x, float &value);
template void stringToData (const string &x, double &value);
bool equal_nocase (const string &a, const string &b)
{
if (a.size()!=b.size()) return false;
for (tsize m=0; m<a.size(); ++m)
if (tolower(a[m])!=tolower(b[m])) return false;
return true;
}
string tolower(const string &input)
{
string result=input;
for (tsize m=0; m<result.size(); ++m)
result[m]=char(tolower(result[m]));
return result;
}
namespace {
void openmp_status()
{
int threads = openmp_max_threads();
if (threads>1)
cout << "OpenMP active: max. " << threads << " threads. " << endl;
}
void SSE_status()
{
#if(defined(PLANCK_HAVE_SSE)||defined(PLANCK_HAVE_SSE2))
cout << "Processor features detected: ";
#if(defined(PLANCK_HAVE_SSE)&&defined(PLANCK_HAVE_SSE2))
cout << "SSE, SSE2" << endl;
#elif(defined(PLANCK_HAVE_SSE))
cout << "SSE" << endl;
#else
cout << "SSE2" << endl;
#endif
#endif
}
} //unnamed namespace
void announce (const string &name)
{
string version = "v2.20";
string name2 = name+" "+version;
cout << endl << "+-";
for (tsize m=0; m<name2.length(); ++m) cout << "-";
cout << "-+" << endl;
cout << "| " << name2 << " |" << endl;
cout << "+-";
for (tsize m=0; m<name2.length(); ++m) cout << "-";
cout << "-+" << endl << endl;
SSE_status();
openmp_status();
cout << endl;
}
void module_startup (const string &name, int argc, const char **,
int argc_expected, const string &argv_expected, bool verbose)
{
if (verbose) announce (name);
if (argc==argc_expected) return;
cerr << "Usage: " << name << " " << argv_expected << endl;
planck_fail_quietly ("Incorrect usage");
}
void parse_file (const string &filename, map<string,string> &dict)
{
int lineno=0;
dict.clear();
ifstream inp(filename.c_str());
planck_assert (inp,"Could not open parameter file '"+filename+"'.");
while (inp)
{
string line;
getline(inp, line);
++lineno;
// remove potential carriage returns at the end of the line
line=line.substr(0,line.find("\r"));
line=line.substr(0,line.find("#"));
line=trim(line);
if (line.size()>0)
{
string::size_type eqpos=line.find("=");
if (eqpos!=string::npos)
{
string key=trim(line.substr(0,eqpos)),
value=trim(line.substr(eqpos+1,string::npos));
if (key=="")
cerr << "Warning: empty key in '" << filename << "', line "
<< lineno << endl;
else
{
if (dict.find(key)!=dict.end())
cerr << "Warning: key '" << key << "' multiply defined in '"
<< filename << "', line " << lineno << endl;
dict[key]=value;
}
}
else
cerr << "Warning: unrecognized format in '" << filename << "', line "
<< lineno << ":\n" << line << endl;
}
}
}
void calcShareGeneral (int64 glo, int64 ghi, int64 nshares, int64 myshare,
int64 &lo, int64 &hi)
{
int64 nwork = ghi-glo;
int64 nbase = nwork/nshares;
int64 additional = nwork%nshares;
lo = glo+myshare*nbase + ((myshare<additional) ? myshare : additional);
hi = lo+nbase+(myshare<additional);
}
namespace {
template<typename T> void split (istream &stream, vector<T> &list)
{
while (stream)
{
string word;
stream >> word;
planck_assert (stream||stream.eof(),
string("error while splitting stream into ") + type2typename<T>()
+ "components");
if (stream) list.push_back(stringToData<T>(word));
}
}
} // unnamed namespace
template<typename T> void split (const string &inp, vector<T> &list)
{
istringstream stream(inp);
split (stream,list);
}
template void split (const string &inp, vector<string> &list);
template void split (const string &inp, vector<float> &list);
template void split (const string &inp, vector<double> &list);
template void split (const string &inp, vector<int> &list);
template void split (const string &inp, vector<long> &list);
void tokenize (const string &inp, char delim, vector<string> &list)
{
istringstream stream(inp);
string token;
list.clear();
while (getline(stream,token,delim))
list.push_back(token);
}

383
external/healpix/cxxsupport/cxxutils.h vendored Normal file
View file

@ -0,0 +1,383 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file cxxutils.h
* Various convenience functions used by the Planck LevelS package.
*
* Copyright (C) 2002 - 2010 Max-Planck-Society
* \author Martin Reinecke \author Reinhard Hell
*/
#ifndef PLANCK_CXXUTILS_H
#define PLANCK_CXXUTILS_H
#include <algorithm>
#include <string>
#include <map>
#include <vector>
#include <cmath>
#include "error_handling.h"
#include "datatypes.h"
/*! \defgroup mathutilsgroup Mathematical helper functions */
/*! \{ */
/*! Returns \e true if | \a a-b | < \a epsilon * | \a b |, else \e false. */
template<typename F> inline bool approx (F a, F b, F epsilon=1e-5)
{
using namespace std;
return abs(a-b) < (epsilon*abs(b));
}
/*! Returns \e true if | \a a-b | < \a epsilon, else \e false. */
template<typename F> inline bool abs_approx (F a, F b, F epsilon=1e-5)
{
using namespace std;
return abs(a-b) < epsilon;
}
/*! Returns the largest integer which is smaller than (or equal to) \a arg. */
template<typename I, typename F> inline I ifloor (F arg)
{
using namespace std;
return I(floor(arg));
}
/*! Returns the integer which is nearest to \a arg. */
template<typename I, typename F> inline I nearest (F arg)
{ return ifloor<I>(arg+0.5); }
/*! Returns \a v1+v2 if \a v1<0, \a v1-v2 if \a v1>=v2, else \a v1.
\a v1 can be positive or negative; \a v2 must be positive. */
template<typename T> inline T weak_modulo (T v1, T v2)
{ return (v1>=0) ? ((v1<v2) ? v1 : (v1-v2)) : (v1+v2); }
/*! Returns the remainder of the division \a v1/v2.
The result is non-negative.
\a v1 can be positive or negative; \a v2 must be positive. */
inline double fmodulo (double v1, double v2)
{
using namespace std;
return (v1>=0) ? ((v1<v2) ? v1 : fmod(v1,v2)) : (fmod(v1,v2)+v2);
}
/*! Returns the remainder of the division \a v1/v2.
The result is non-negative.
\a v1 can be positive or negative; \a v2 must be positive. */
template<typename I> inline I imodulo (I v1, I v2)
{ I v=v1%v2; return (v>=0) ? v : v+v2; }
/*! Returns -1 if \a signvalue is negative, else +1. */
template<typename T> inline T sign (const T& signvalue)
{ return (signvalue>=0) ? 1 : -1; }
/*! Returns \a val*pow(-1,m) */
template<typename T, typename I> inline T xpow (I m, T val)
{ return (m&1) ? -val : val; }
template <typename I, bool g4> struct isqrt_helper__
{};
template <typename I> struct isqrt_helper__ <I, false>
{
static uint32 isqrt (I arg)
{
using namespace std;
return uint32 (sqrt(arg+0.5));
}
};
template <typename I> struct isqrt_helper__ <I, true>
{
static uint32 isqrt (I arg)
{
using namespace std;
long double arg2 = static_cast<long double>(arg)+0.5;
return uint32 (sqrt(arg2));
}
};
/*! Returns the integer \a n, which fulfills \a n*n<=arg<(n+1)*(n+1). */
template<typename I> inline uint32 isqrt (I arg)
{ return isqrt_helper__<I,(sizeof(I)>4)>::isqrt(arg); }
/*! Returns the largest integer \a n that fulfills \a 2^n<=arg. */
template<typename I> inline unsigned int ilog2 (I arg)
{
unsigned int res=0;
while (arg > 0x0000FFFF) { res+=16; arg>>=16; }
if (arg > 0x000000FF) { res|=8; arg>>=8; }
if (arg > 0x0000000F) { res|=4; arg>>=4; }
if (arg > 0x00000003) { res|=2; arg>>=2; }
if (arg > 0x00000001) { res|=1; }
return res;
}
/*! Returns \a atan2(y,x) if \a x!=0 or \a y!=0; else returns 0. */
inline double safe_atan2 (double y, double x)
{
using namespace std;
return ((x==0.) && (y==0.)) ? 0.0 : atan2(y,x);
}
/*! Helper function for linear interpolation (or extrapolation).
The array must be ordered in ascending order; no two values may be equal. */
template<typename T, typename Iter, typename Comp> inline void interpol_helper
(const Iter &begin, const Iter &end, const T &val, Comp comp, tsize &idx,
T &frac)
{
using namespace std;
planck_assert((end-begin)>1,"sequence too small for interpolation");
idx = lower_bound(begin,end,val,comp)-begin;
if (idx>0) --idx;
idx = min(tsize(end-begin-2),idx);
frac = (val-begin[idx])/(begin[idx+1]-begin[idx]);
}
/*! Helper function for linear interpolation (or extrapolation).
The array must be ordered in ascending order; no two values may be equal. */
template<typename T, typename Iter> inline void interpol_helper
(const Iter &begin, const Iter &end, const T &val, tsize &idx, T &frac)
{ interpol_helper (begin,end,val,std::less<T>(),idx,frac); }
/*! \} */
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c)
{ return (a==b) && (a==c); }
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c,
const T &d)
{ return (a==b) && (a==c) && (a==d); }
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c,
const T &d, const T &e)
{ return (a==b) && (a==c) && (a==d) && (a==e); }
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c,
const T &d, const T &e, const T &f)
{ return (a==b) && (a==c) && (a==d) && (a==e) && (a==f); }
template<typename It, typename Comp> class IdxComp__
{
private:
It begin;
Comp comp;
public:
IdxComp__ (It begin_, Comp comp_): begin(begin_), comp(comp_) {}
bool operator() (std::size_t a, std::size_t b) const
{ return comp(*(begin+a),*(begin+b)); }
};
/*! Performs an indirect sort on the supplied iterator range and returns in
\a idx a \a vector containing the indices of the smallest, second smallest,
third smallest, etc. element, according to \a comp. */
template<typename It, typename T2, typename Comp>
inline void buildIndex (It begin, It end, std::vector<T2> &idx, Comp comp)
{
using namespace std;
T2 num=end-begin;
idx.resize(num);
for (T2 i=0; i<num; ++i) idx[i] = i;
sort (idx.begin(),idx.end(),IdxComp__<It,Comp>(begin,comp));
}
/*! Performs an indirect sort on the supplied iterator range and returns in
\a idx a \a vector containing the indices of the smallest, second smallest,
third smallest, etc. element. */
template<typename It, typename T2> inline void buildIndex (It begin, It end,
std::vector<T2> &idx)
{
using namespace std;
typedef typename iterator_traits<It>::value_type T;
buildIndex(begin,end,idx,less<T>());
}
/*! Sorts the supplied iterator range according to the order given by \a idx.
The operation is done out of place and requires temporary extra storage. */
template<typename It, typename T2> inline void sortByIndex (It begin, It end,
const std::vector<T2> &idx)
{
using namespace std;
typedef typename iterator_traits<It>::value_type T;
T2 num=end-begin;
T *tmp= new T[num];
for (T2 i=0; i<num; ++i) tmp[i]=*(begin+i);
for (T2 i=0; i<num; ++i) *(begin+i) = tmp[idx[i]];
delete[] tmp;
}
/*! Sorts the supplied iterator range according to the order given by \a idx.
The operation is done in place. */
template<typename It, typename T2> inline void sortByIndex_inplace
(It begin, It end, const std::vector<T2> &idx)
{
using namespace std;
typedef typename iterator_traits<It>::value_type T;
T2 num=end-begin;
vector<bool> done(num,false);
T2 cnt=0;
while (cnt<num)
{
if (!done[cnt]) // new cycle
{
T tmp(*(begin+cnt));
T2 cnt2 = cnt;
T2 cnt3 = idx[cnt];
while (cnt3!=cnt)
{
done[cnt2]=true;
*(begin+cnt2)=*(begin+cnt3);
cnt2=cnt3;
cnt3=idx[cnt3];
}
*(begin+cnt2) = tmp;
}
++cnt;
}
}
template<typename It, typename Comp> inline void indirectSort (It begin, It end,
Comp comp)
{
using namespace std;
typedef typename iterator_traits<It>::value_type T;
vector<std::size_t> idx;
buildIndex (begin,end,idx,comp);
sortByIndex (begin,end,idx);
}
template<typename It> inline void indirectSort (It begin, It end)
{
using namespace std;
typedef typename iterator_traits<It>::value_type T;
indirectSort(begin,end,less<T>());
}
/*! \defgroup stringutilsgroup String handling helper functions */
/*! \{ */
/*! Returns the string \a orig without leading and trailing whitespace. */
std::string trim (const std::string &orig);
/*! Returns a string containing the text representation of \a x.
Care is taken that no information is lost in the conversion. */
template<typename T> std::string dataToString(const T &x);
template<> std::string dataToString (const bool &x);
template<> std::string dataToString (const std::string &x);
template<> std::string dataToString (const float &x);
template<> std::string dataToString (const double &x);
/*! Returns a string containing the text representation of \a x, padded
with leading zeroes to \a width characters. */
std::string intToString(int64 x, tsize width);
/*! Reads a value of a given datatype from a string */
template<typename T> void stringToData (const std::string &x, T &value);
template<> void stringToData (const std::string &x, std::string &value);
template<> void stringToData (const std::string &x, bool &value);
/*! Reads a value of a given datatype from a string */
template<typename T> inline T stringToData (const std::string &x)
{ T result; stringToData(x,result); return result; }
/*! Parses the file \a filename and returns the key/value pairs in \a dict. */
void parse_file (const std::string &filename,
std::map<std::string,std::string> &dict);
/*! Case-insensitive string comparison
Returns \a true, if \a a and \a b differ only in capitalisation,
else \a false. */
bool equal_nocase (const std::string &a, const std::string &b);
/*! Returns lowercase version of \a input. */
std::string tolower(const std::string &input);
/*! \} */
/*! Prints a banner containing \a name, as well as some information about the
source code and the parallelisation techniques enabled. */
void announce (const std::string &name);
/*! Prints a banner containing \a name and checks if \a argc==argc_expected.
If not, a usage description is given and the program is terminated. */
void module_startup (const std::string &name, int argc, const char **argv,
int argc_expected, const std::string &argv_expected, bool verbose=true);
/*! Divides the index range [\a glo; \a ghi) into \a nshares approximately
equal parts, and returns the sub-range [\a lo; \a hi) of the
part with the number \a myshare (first part has index 0). */
void calcShareGeneral (int64 glo, int64 ghi, int64 nshares, int64 myshare,
int64 &lo, int64 &hi);
/*! Helper class for dividing a range of work items into chunks of specified
size. */
class chunkMaker
{
private:
uint64 s_full, s_chunk, offset;
public:
/*! Creates an object that produces chunk information for \a s_full_
work items and a desired chunk size of \a s_chunk_. */
chunkMaker (uint64 s_full_, uint64 s_chunk_)
: s_full(s_full_), s_chunk(s_chunk_), offset(0) {}
/*! Returns the total number of chunks. */
uint64 nchunks() const
{ return (s_full+s_chunk-1)/s_chunk; }
/*! Returns the start index of the next chunk in \a start, and its size
in \a size. If all chunks have been processed already, the return
value is \a false, else \a true. */
bool getNext (uint64 &start, uint64 &size)
{
using namespace std;
if (offset>=s_full) return false;
start=offset;
size=min(s_chunk,s_full-offset);
offset+=s_chunk;
return true;
}
};
/*! Tries to split \a inp into a white-space separated list of values of
type \a T, and appends them to \a list. */
template<typename T> void split (const std::string &inp, std::vector<T> &list);
/*! Resizes \a container to zero and releases its memory. Typically used for
std::vector.
Taken from http://www.gotw.ca/gotw/054.htm */
template<typename T> inline void releaseMemory (T &container)
{ T().swap(container); }
/*! Releases all unused memory that \a container might have. Typically used for
std::vector.
Taken from http://www.gotw.ca/gotw/054.htm */
template<typename T> inline void shrinkToFit (T &container)
{ T(container).swap(container); }
/*! Breaks the string \a inp into tokens separated by \a delim, and returns them
in \a list. */
void tokenize (const std::string &inp, char delim,
std::vector<std::string> &list);
#endif

284
external/healpix/cxxsupport/datatypes.h vendored Normal file
View file

@ -0,0 +1,284 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file datatypes.h
* This file defines various platform-independent data types.
* If any of the requested types is not available, compilation aborts
* with an error (unfortunately a rather obscure one).
*
* Copyright (C) 2004, 2008, 2009, 2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_DATATYPES_H
#define PLANCK_DATATYPES_H
#include <string>
#include <cstddef>
#include "error_handling.h"
// Template magic to select the proper data types. These templates
// should not be used outside this file.
template <typename T, bool equalSize> struct sizeChooserHelper__
{ typedef void TYPE; };
template <typename T> struct sizeChooserHelper__<T,true>
{ typedef T TYPE; };
template <typename T1, typename T2, typename T3> struct sizeChooserHelper2__
{ typedef T1 TYPE; };
template <typename T2, typename T3> struct sizeChooserHelper2__ <void, T2, T3>
{ typedef T2 TYPE; };
template <typename T3> struct sizeChooserHelper2__ <void, void, T3>
{ typedef T3 TYPE; };
template <> struct sizeChooserHelper2__ <void, void, void>
{ };
template <int sz, typename T1, typename T2=char, typename T3=char>
struct sizeChooser__
{
typedef typename sizeChooserHelper2__
<typename sizeChooserHelper__<T1,sizeof(T1)==sz>::TYPE,
typename sizeChooserHelper__<T2,sizeof(T2)==sz>::TYPE,
typename sizeChooserHelper__<T3,sizeof(T3)==sz>::TYPE >::TYPE TYPE;
};
typedef signed char int8;
typedef unsigned char uint8;
typedef sizeChooser__<2, short, int>::TYPE
int16;
typedef sizeChooser__<2, unsigned short, unsigned int>::TYPE
uint16;
typedef sizeChooser__<4, int, long, short>::TYPE
int32;
typedef sizeChooser__<4, unsigned int, unsigned long, unsigned short>::TYPE
uint32;
typedef sizeChooser__<8, long, long long>::TYPE
int64;
typedef sizeChooser__<8, unsigned long, unsigned long long>::TYPE
uint64;
typedef sizeChooser__<4, float, double>::TYPE
float32;
typedef sizeChooser__<8, double, long double>::TYPE
float64;
/*! unsigned integer type which should be used for array sizes */
typedef std::size_t tsize;
/*! signed integer type which should be used for relative array indices */
typedef std::ptrdiff_t tdiff;
/*! mapping of Planck data types to integer constants */
enum PDT {
PLANCK_INT8 = 0,
PLANCK_UINT8 = 1,
PLANCK_INT16 = 2,
PLANCK_UINT16 = 3,
PLANCK_INT32 = 4,
PLANCK_UINT32 = 5,
PLANCK_INT64 = 6,
PLANCK_UINT64 = 7,
PLANCK_FLOAT32 = 8,
PLANCK_FLOAT64 = 9,
PLANCK_BOOL = 10,
PLANCK_STRING = 11,
PLANCK_INVALID = -1 };
/*! Returns the \a PDT constant associated with \a T. */
template<typename T> inline PDT planckType();
template<> inline PDT planckType<int8> () { return PLANCK_INT8; }
template<> inline PDT planckType<uint8> () { return PLANCK_UINT8; }
template<> inline PDT planckType<int16> () { return PLANCK_INT16; }
template<> inline PDT planckType<uint16> () { return PLANCK_UINT16; }
template<> inline PDT planckType<int32> () { return PLANCK_INT32; }
template<> inline PDT planckType<uint32> () { return PLANCK_UINT32; }
template<> inline PDT planckType<int64> () { return PLANCK_INT64; }
template<> inline PDT planckType<uint64> () { return PLANCK_UINT64; }
template<> inline PDT planckType<float32> () { return PLANCK_FLOAT32;}
template<> inline PDT planckType<float64> () { return PLANCK_FLOAT64;}
template<> inline PDT planckType<bool> () { return PLANCK_BOOL; }
template<> inline PDT planckType<std::string>() { return PLANCK_STRING; }
/*! Returns the size (in bytes) of the Planck data type \a type. */
inline int type2size (PDT type)
{
switch (type)
{
case PLANCK_INT8 :
case PLANCK_UINT8 :
case PLANCK_BOOL :
case PLANCK_STRING : return 1;
case PLANCK_INT16 :
case PLANCK_UINT16 : return 2;
case PLANCK_INT32 :
case PLANCK_UINT32 :
case PLANCK_FLOAT32: return 4;
case PLANCK_INT64 :
case PLANCK_UINT64 :
case PLANCK_FLOAT64: return 8;
default:
planck_fail ("type2size: unsupported data type");
}
}
/*! Converts the string \a type to a \a PDT. */
inline PDT string2type(const std::string &type)
{
if (type=="FLOAT64") return PLANCK_FLOAT64;
if (type=="FLOAT32") return PLANCK_FLOAT32;
if (type=="INT8") return PLANCK_INT8;
if (type=="UINT8") return PLANCK_UINT8;
if (type=="INT16") return PLANCK_INT16;
if (type=="UINT16") return PLANCK_UINT16;
if (type=="INT32") return PLANCK_INT32;
if (type=="UINT32") return PLANCK_UINT32;
if (type=="INT64") return PLANCK_INT64;
if (type=="UINT64") return PLANCK_UINT64;
if (type=="BOOL") return PLANCK_BOOL;
if (type=="STRING") return PLANCK_STRING;
planck_fail ("string2type: unknown data type '"+type+"'");
}
/*! Converts the Planck data type \a type to a C string. */
inline const char *type2string (PDT type)
{
switch (type)
{
case PLANCK_INT8 : return "INT8";
case PLANCK_UINT8 : return "UINT8";
case PLANCK_INT16 : return "INT16";
case PLANCK_UINT16 : return "UINT16";
case PLANCK_INT32 : return "INT32";
case PLANCK_UINT32 : return "UINT32";
case PLANCK_INT64 : return "INT64";
case PLANCK_UINT64 : return "UINT64";
case PLANCK_FLOAT32: return "FLOAT32";
case PLANCK_FLOAT64: return "FLOAT64";
case PLANCK_BOOL : return "BOOL";
case PLANCK_STRING : return "STRING";
default:
planck_fail ("type2string: unsupported data type");
}
}
/*! Returns a C string describing the data type \a T. */
template<typename T> inline const char *type2typename ();
template<> inline const char *type2typename<signed char> ()
{ return "signed char"; }
template<> inline const char *type2typename<unsigned char> ()
{ return "unsigned char"; }
template<> inline const char *type2typename<short> ()
{ return "short"; }
template<> inline const char *type2typename<unsigned short> ()
{ return "unsigned short"; }
template<> inline const char *type2typename<int> ()
{ return "int"; }
template<> inline const char *type2typename<unsigned int> ()
{ return "unsigned int"; }
template<> inline const char *type2typename<long> ()
{ return "long"; }
template<> inline const char *type2typename<unsigned long> ()
{ return "unsigned long"; }
template<> inline const char *type2typename<long long> ()
{ return "long long"; }
template<> inline const char *type2typename<unsigned long long> ()
{ return "unsigned long long"; }
template<> inline const char *type2typename<float> ()
{ return "float"; }
template<> inline const char *type2typename<double> ()
{ return "double"; }
template<> inline const char *type2typename<bool> ()
{ return "bool"; }
template<> inline const char *type2typename<std::string> ()
{ return "std::string"; }
/*! mapping of "native" data types to integer constants */
enum NDT {
NAT_CHAR,
NAT_SCHAR,
NAT_UCHAR,
NAT_SHORT,
NAT_USHORT,
NAT_INT,
NAT_UINT,
NAT_LONG,
NAT_ULONG,
NAT_LONGLONG,
NAT_ULONGLONG,
NAT_FLOAT,
NAT_DOUBLE,
NAT_LONGDOUBLE,
NAT_BOOL };
/*! Returns the \a NDT constant associated with \a T. */
template<typename T> inline NDT nativeType();
template<> inline NDT nativeType<char> () { return NAT_CHAR; }
template<> inline NDT nativeType<signed char> () { return NAT_SCHAR; }
template<> inline NDT nativeType<unsigned char> () { return NAT_UCHAR; }
template<> inline NDT nativeType<short> () { return NAT_SHORT; }
template<> inline NDT nativeType<unsigned short> () { return NAT_USHORT; }
template<> inline NDT nativeType<int> () { return NAT_INT; }
template<> inline NDT nativeType<unsigned int> () { return NAT_UINT; }
template<> inline NDT nativeType<long> () { return NAT_LONG; }
template<> inline NDT nativeType<unsigned long> () { return NAT_ULONG; }
template<> inline NDT nativeType<long long> () { return NAT_LONGLONG; }
template<> inline NDT nativeType<unsigned long long>() { return NAT_ULONGLONG; }
template<> inline NDT nativeType<float> () { return NAT_FLOAT; }
template<> inline NDT nativeType<double> () { return NAT_DOUBLE; }
template<> inline NDT nativeType<long double> () { return NAT_LONGDOUBLE;}
template<> inline NDT nativeType<bool> () { return NAT_BOOL; }
/*! Returns the size (in bytes) of the native data type \a type. */
inline int ndt2size (NDT type)
{
switch (type)
{
case NAT_CHAR :
case NAT_SCHAR :
case NAT_UCHAR : return sizeof(char);
case NAT_SHORT :
case NAT_USHORT : return sizeof(short);
case NAT_INT :
case NAT_UINT : return sizeof(int);
case NAT_LONG :
case NAT_ULONG : return sizeof(long);
case NAT_LONGLONG :
case NAT_ULONGLONG : return sizeof(long long);
case NAT_FLOAT : return sizeof(float);
case NAT_DOUBLE : return sizeof(double);
case NAT_LONGDOUBLE: return sizeof(long double);
case NAT_BOOL : return sizeof(bool);
default:
planck_fail ("ndt2size: unsupported data type");
}
}
#endif

View file

@ -0,0 +1,56 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Utilities for error reporting
*
* Copyright (C) 2003 - 2010 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "error_handling.h"
#include <iostream>
#include <string>
using namespace std;
PlanckError::PlanckError(const string &message) : msg (message) {}
PlanckError::PlanckError(const char *message) : msg (message) {}
void planck_failure__(const char *file, int line, const char *func,
const string &msg)
{
cerr << "Error encountered at " << file << ", line " << line << endl;
if (func) cerr << "(function " << func << ")" << endl;
if (msg!="") cerr << endl << msg << endl;
cerr << endl;
}
void planck_failure__(const char *file, int line, const char *func,
const char *msg)
{ planck_failure__ (file,line,func,string(msg)); }
void killjob__()
{ throw; }

View file

@ -0,0 +1,100 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Utilities for error reporting
*
* Copyright (C) 2003 - 2010 Max-Planck-Society
* Authors: Reinhard Hell, Martin Reinecke
*/
#ifndef PLANCK_ERROR_HANDLING_H
#define PLANCK_ERROR_HANDLING_H
#include <string>
#include <iostream>
#if defined (__GNUC__)
#define PLANCK_FUNC_NAME__ __PRETTY_FUNCTION__
#else
#define PLANCK_FUNC_NAME__ 0
#endif
void planck_failure__(const char *file, int line, const char *func,
const std::string &msg);
void planck_failure__(const char *file, int line, const char *func,
const char *msg);
void killjob__();
class PlanckError
{
private:
std::string msg;
public:
explicit PlanckError(const std::string &message);
explicit PlanckError(const char *message);
virtual const char* what() const
{ return msg.c_str(); }
virtual ~PlanckError() {}
};
/*! \defgroup errorgroup Error handling */
/*! \{ */
/*! Writes diagnostic output and exits with an error status. */
#define planck_fail(msg) \
do { planck_failure__(__FILE__,__LINE__,PLANCK_FUNC_NAME__,msg); \
throw PlanckError(msg); } while(0)
/*! Throws a PlanckError without diagnostic message. */
#define planck_fail_quietly(msg) \
do { throw PlanckError(msg); } while(0)
/*! Writes diagnostic output and exits with an error status if \a testval
is \a false. */
#define planck_assert(testval,msg) \
do { if (testval); else planck_fail(msg); } while(0)
/*! Macro for improving error diagnostics. Should be placed immediately
after the opening brace of \c main(). Must be used in conjunction with
\c PLANCK_DIAGNOSIS_END. */
#define PLANCK_DIAGNOSIS_BEGIN try {
/*! Macro for improving error diagnostics. Should be placed immediately
before the closing brace of \c main(). Must be used in conjunction with
\c PLANCK_DIAGNOSIS_BEGIN. */
#define PLANCK_DIAGNOSIS_END \
} \
catch (PlanckError &) \
{ killjob__(); /* no need for further diagnostics; they were shown already */ } \
catch (std::exception &e) \
{ std::cerr << "std::exception: " << e.what() << std::endl; killjob__(); } \
catch (...) \
{ std::cerr << "Unknown exception" << std::endl; killjob__(); }
/*! \} */
#endif

View file

@ -0,0 +1,109 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2004-2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_FFTPACK_SUPPORT_H
#define PLANCK_FFTPACK_SUPPORT_H
#include "ls_fft.h"
#include "arr.h"
#include "xcomplex.h"
class cfft
{
private:
tsize n;
complex_plan plan;
public:
cfft () : n(0), plan(0) {}
cfft (tsize size_)
: n(size_), plan(make_complex_plan(size_)) {}
~cfft ()
{ if (plan!=0) kill_complex_plan (plan); }
void Set (tsize size_)
{
if (plan!=0) kill_complex_plan (plan);
n=size_;
plan=make_complex_plan(size_);
}
tsize size() const
{ return n; }
void forward (double *data)
{ complex_plan_forward(plan,data); }
void backward (double *data)
{ complex_plan_backward(plan,data); }
void forward (xcomplex<double> *data)
{ complex_plan_forward(plan,&(data->re)); }
void backward (xcomplex<double> *data)
{ complex_plan_backward(plan,&(data->re)); }
void forward (arr<xcomplex<double> >&data)
{ forward(&(data[0].re)); }
void backward (arr<xcomplex<double> >&data)
{ backward(&(data[0].re)); }
};
class rfft
{
private:
tsize n;
real_plan plan;
public:
rfft () : n(0), plan(0) {}
rfft (tsize size_)
: n(size_), plan(make_real_plan(size_)) {}
~rfft ()
{ if (plan!=0) kill_real_plan (plan); }
void Set (tsize size_)
{
if (plan!=0) kill_real_plan (plan);
n=size_;
plan=make_real_plan(size_);
}
tsize size() const
{ return n; }
void forward_fftpack (double *data)
{ real_plan_forward_fftpack(plan,data); }
void backward_fftpack (double *data)
{ real_plan_backward_fftpack(plan,data); }
void forward_fftpack (arr<double> &data)
{ forward_fftpack(&(data[0])); }
void backward_fftpack (arr<double> &data)
{ backward_fftpack(&(data[0])); }
void forward_c (arr<xcomplex<double> >&data)
{ real_plan_forward_c(plan,&(data[0].re)); }
void backward_c (arr<xcomplex<double> >&data)
{ real_plan_backward_c(plan,&(data[0].re)); }
};
#endif

View file

@ -0,0 +1,792 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* This file contains the implementation of the FITS I/O helper class
* used by the Planck LevelS package.
*
* Copyright (C) 2002 - 2009 Max-Planck-Society
* Author: Martin Reinecke
*/
#include <sstream>
#include <cstring>
#include <vector>
#include "fitsio.h"
#include "fitshandle.h"
#include "cxxutils.h"
#include "safe_cast.h"
#define FPTR (static_cast<fitsfile *> (fptr))
#define OFPTR (static_cast<fitsfile *> (orig.fptr))
using namespace std;
namespace {
template<typename T> inline int fitsType();
template<> inline int fitsType<float> () { return TFLOAT; }
template<> inline int fitsType<double>() { return TDOUBLE; }
int type2bitpix (PDT type)
{
switch (type)
{
case PLANCK_FLOAT32: return FLOAT_IMG;
case PLANCK_FLOAT64: return DOUBLE_IMG;
default: planck_fail ("unsupported component type");
}
}
/*! Converts a FITS type code (i.e. the data type of a FITS column) to the
corresponding Planck type code. */
PDT ftc2type (int ftc)
{
switch (ftc)
{
case TLOGICAL : return PLANCK_BOOL;
case TBYTE : return PLANCK_INT8;
case TSHORT : return PLANCK_INT16;
case TINT :
case TINT32BIT: return PLANCK_INT32;
case TLONGLONG: return PLANCK_INT64;
case TFLOAT : return PLANCK_FLOAT32;
case TDOUBLE : return PLANCK_FLOAT64;
case TSTRING : return PLANCK_STRING;
default: planck_fail ("unsupported component type");
}
}
/*! Converts a Planck type code to the corresponding FITS type code
(i.e. the data type of a FITS column). */
int type2ftc (PDT type)
{
switch (type)
{
case PLANCK_BOOL : return TLOGICAL;
case PLANCK_INT8 :
case PLANCK_UINT8 : return TBYTE;
case PLANCK_INT16 : return TSHORT;
case PLANCK_INT32 : return TINT;
case PLANCK_INT64 : return TLONGLONG;
case PLANCK_FLOAT32: return TFLOAT;
case PLANCK_FLOAT64: return TDOUBLE;
case PLANCK_STRING : return TSTRING;
default: planck_fail ("unsupported component type");
}
}
const char *type2fitschar (PDT type)
{
switch (type)
{
case PLANCK_BOOL : return "L";
case PLANCK_FLOAT32: return "E";
case PLANCK_FLOAT64: return "D";
case PLANCK_INT8 :
case PLANCK_UINT8 : return "B";
case PLANCK_INT16 : return "I";
case PLANCK_INT32 : return "J";
case PLANCK_INT64 : return "K";
case PLANCK_STRING : return "A";
default:
planck_fail(string("unknown data type ")+type2string(type));
}
}
const char *type2asciiform (PDT type)
{
switch (type)
{
case PLANCK_FLOAT32: return "E14.7";
case PLANCK_FLOAT64: return "D23.15";
case PLANCK_UINT8 : return "I3";
case PLANCK_INT8 : return "I4";
case PLANCK_INT16 : return "I6";
case PLANCK_INT32 : return "I11";
case PLANCK_INT64 : return "I22";
default:
planck_fail(string("unknown data type ")+type2string(type));
}
}
string fixkey (const string &key)
{
for (tsize m=0; m<key.size(); ++m)
if (islower(key[m])) return string("HIERARCH "+key);
return key;
}
} // unnamed namespace
fitscolumn::fitscolumn()
: repcount_(0), type_(PLANCK_INVALID) {}
fitscolumn::fitscolumn (const string &nm, const string &un, int64 rc, PDT tp)
: name_(nm), unit_(un), repcount_(rc), type_(tp) {}
void fitshandle::check_errors() const
{
char msg[81];
if (status==0)
{
while (fits_read_errmsg(msg))
cerr << "STALE FITS ERROR MESSAGE: " << msg << endl;
fits_clear_errmsg();
return;
}
fits_get_errstatus (status, msg);
cerr << msg << endl;
while (fits_read_errmsg(msg)) cerr << msg << endl;
fits_clear_errmsg();
status=0;
planck_fail("FITS error");
}
void fitshandle::clean_data()
{
if (!fptr) return;
axes_.clear();
columns_.clear();
hdutype_=INVALID;
bitpix_=INVALID;
nrows_=0;
}
void fitshandle::clean_all()
{
if (!fptr) return;
clean_data();
fits_close_file (FPTR, &status);
check_errors();
fptr=0;
}
bool fitshandle::table_hdu (tsize col) const
{
if ((hdutype_!=ASCII_TBL) && (hdutype_!=BINARY_TBL)) return false;
if ((col<=0) || (col>columns_.size())) return false;
return true;
}
bool fitshandle::image_hdu () const
{ return hdutype_==IMAGE_HDU; }
void fitshandle::init_image()
{
int naxis;
fits_get_img_type (FPTR, &bitpix_, &status);
fits_get_img_dim (FPTR, &naxis, &status);
check_errors();
arr<LONGLONG> naxes(naxis);
fits_get_img_sizell (FPTR, naxis, &naxes[0], &status);
for (long m=0; m<naxis; ++m) axes_.push_back(naxes[naxis-m-1]);
check_errors();
}
void fitshandle::init_asciitab()
{
char ttype[81], tunit[81], tform[81];
int ncol, typecode;
fits_get_num_cols (FPTR, &ncol, &status);
{ LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
check_errors();
for (int m=1; m<=ncol; ++m)
{
fits_get_acolparms (FPTR, m, ttype, 0, tunit, tform,
0, 0, 0, 0, &status);
fits_ascii_tform (tform, &typecode, 0,0, &status);
check_errors();
columns_.push_back (fitscolumn (ttype,tunit,1,ftc2type(typecode)));
}
}
void fitshandle::init_bintab()
{
char ttype[81], tunit[81], tform[81];
LONGLONG repc;
int ncol, typecode;
fits_get_num_cols (FPTR, &ncol, &status);
{ LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
check_errors();
for (int m=1; m<=ncol; ++m)
{
fits_get_bcolparmsll (FPTR, m, ttype, tunit, tform, &repc,
0, 0, 0, 0, &status);
fits_binary_tform (tform, &typecode, 0,0, &status);
check_errors();
columns_.push_back (fitscolumn (ttype,tunit,repc,ftc2type(typecode)));
}
}
void fitshandle::init_data()
{
clean_data();
fits_get_hdu_type (FPTR, &hdutype_, &status);
check_errors();
switch(hdutype_)
{
case IMAGE_HDU:
init_image(); break;
case ASCII_TBL:
init_asciitab(); break;
case BINARY_TBL:
init_bintab(); break;
default:
planck_fail("init_data(): unsupported HDU type"); break;
}
}
void fitshandle::read_col (int colnum, void *data, int64 ndata, PDT type,
int64 offset) const
{
planck_assert(table_hdu(colnum),"incorrect FITS table access");
int64 repc = columns_[colnum-1].repcount();
planck_assert (ndata<=(repc*nrows_-offset),"read_column(): array too large");
int64 frow = offset/repc+1;
int64 felem = offset%repc+1;
fits_read_col (FPTR, type2ftc(type), colnum, frow, felem, ndata, 0, data, 0,
&status);
check_errors();
}
void fitshandle::write_col (int colnum, const void *data, int64 ndata,
PDT type, int64 offset)
{
planck_assert(table_hdu(colnum),"incorrect FITS table access");
int64 repc = columns_[colnum-1].repcount();
int64 frow = offset/repc+1;
int64 felem = offset%repc+1;
fits_write_col (FPTR, type2ftc(type), colnum, frow, felem, ndata,
const_cast<void *>(data), &status);
nrows_ = max(nrows_,offset+ndata);
check_errors();
}
void fitshandle::getKeyHelper(const string &name) const
{
if (status==KEY_NO_EXIST)
{
fits_clear_errmsg();
status=0;
planck_fail("fitshandle::get_key(): key '"+name+"' not found");
}
check_errors();
}
void fitshandle::open (const string &fname)
{
clean_all();
fitsfile *ptr;
fits_open_file(&ptr, fname.c_str(), READONLY, &status);
fptr=ptr;
check_errors();
init_data();
}
void fitshandle::create (const string &fname)
{
clean_all();
fitsfile *ptr;
fits_create_file(&ptr, fname.c_str(), &status);
fptr=ptr;
fits_write_imghdr(FPTR, 8, 0, 0, &status); // insert empty PHDU
fits_write_date(FPTR, &status);
check_errors();
init_data();
}
// static
void fitshandle::delete_file (const string &name)
{
fitsfile *ptr;
int stat = 0;
fits_open_file(&ptr, name.c_str(), READWRITE, &stat);
fits_delete_file(ptr, &stat);
if (stat==0) return;
char msg[81];
fits_get_errstatus (stat, msg);
cerr << msg << endl;
while (fits_read_errmsg(msg)) cerr << msg << endl;
planck_fail("FITS error");
}
void fitshandle::goto_hdu (int hdu)
{
int curhdu;
fits_get_hdu_num(FPTR,&curhdu);
if (curhdu!=hdu)
{
fits_movabs_hdu(FPTR, hdu, &hdutype_, &status);
check_errors();
init_data();
}
}
int fitshandle::num_hdus () const
{
int result;
fits_get_num_hdus (FPTR, &result, &status);
check_errors();
return result;
}
void fitshandle::insert_bintab (const vector<fitscolumn> &cols,
const string &extname)
{
clean_data();
int ncol=cols.size();
arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
for (long m=0; m<ncol; ++m)
{
strcpy (ttype[m], cols[m].name().c_str());
strcpy (tunit[m], cols[m].unit().c_str());
ostringstream x;
x << cols[m].repcount() << type2fitschar(cols[m].type());
strcpy (tform[m], x.str().c_str());
}
fits_insert_btbl (FPTR, nrows_, ncol, ttype.p0(), tform.p0(), tunit.p0(),
const_cast<char *>(extname.c_str()), 0, &status);
check_errors();
init_data();
}
void fitshandle::insert_asctab (const vector<fitscolumn> &cols,
const string &extname)
{
clean_data();
int ncol=cols.size();
arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
for (long m=0; m<ncol; ++m)
{
strcpy (ttype[m], cols[m].name().c_str());
strcpy (tunit[m], cols[m].unit().c_str());
ostringstream x;
if (cols[m].type()!=TSTRING)
{
planck_assert (cols[m].repcount()==1,"bad repcount for ASCII table");
x << type2asciiform(cols[m].type());
}
else
{
x << "A" << dataToString(cols[m].repcount());
}
strcpy (tform[m], x.str().c_str());
}
fits_insert_atbl (FPTR, 0, nrows_, ncol, ttype.p0(), 0, tform.p0(),
tunit.p0(), const_cast<char *>(extname.c_str()), &status);
check_errors();
init_data();
}
void fitshandle::insert_image (PDT type, const vector<int64> &Axes)
{
clean_data();
arr<LONGLONG> tmpax(Axes.size());
for (long m=0; m<long(Axes.size()); m++) tmpax[m]=Axes[Axes.size()-1-m];
fits_insert_imgll (FPTR, type2bitpix(type), Axes.size(), &tmpax[0], &status);
check_errors();
init_data();
}
template<typename T>
void fitshandle::insert_image (PDT type, const arr2<T> &data)
{
clean_data();
arr<LONGLONG> tmpax(2);
tmpax[0] = data.size2(); tmpax[1] = data.size1();
fits_insert_imgll (FPTR, type2bitpix(type), 2, &tmpax[0], &status);
arr2<T> &tmparr = const_cast<arr2<T> &> (data);
fits_write_img (FPTR, fitsType<T>(), 1, tmpax[0]*tmpax[1],
&tmparr[0][0], &status);
check_errors();
init_data();
}
template void fitshandle::insert_image (PDT type, const arr2<double> &data);
template void fitshandle::insert_image (PDT type, const arr2<float> &data);
void fitshandle::write_checksum()
{
planck_assert(connected(),"handle not connected to a file");
fits_write_chksum (FPTR, &status);
check_errors();
}
const vector<int64> &fitshandle::axes() const
{
planck_assert(image_hdu(),"not connected to an image");
return axes_;
}
const string &fitshandle::colname(int i) const
{
planck_assert(table_hdu(i),"incorrect FITS table access");
return columns_[i-1].name();
}
const string &fitshandle::colunit(int i) const
{
planck_assert(table_hdu(i),"incorrect FITS table access");
return columns_[i-1].unit();
}
int64 fitshandle::repcount(int i) const
{
planck_assert(table_hdu(i),"incorrect FITS table access");
return columns_[i-1].repcount();
}
PDT fitshandle::coltype(int i) const
{
planck_assert(table_hdu(i),"incorrect FITS table access");
return columns_[i-1].type();
}
int fitshandle::ncols() const
{
planck_assert(table_hdu(1),"incorrect FITS table access");
return columns_.size();
}
int64 fitshandle::nrows() const
{
planck_assert(table_hdu(1),"incorrect FITS table access");
return nrows_;
}
int64 fitshandle::nelems(int i) const
{
planck_assert(table_hdu(i),"incorrect FITS table access");
if (columns_[i-1].type()==PLANCK_STRING) return nrows_;
return nrows_*columns_[i-1].repcount();
}
int64 fitshandle::efficientChunkSize(int i) const
{
planck_assert(table_hdu(1),"incorrect FITS table access");
long int res;
fits_get_rowsize(FPTR, &res, &status);
planck_assert(res>=1,"bad recommended FITS chunk size");
check_errors();
return res*columns_[i-1].repcount();
}
void fitshandle::get_all_keys(vector<string> &keys) const
{
keys.clear();
char card[81];
const char *inclist[] = { "*" };
planck_assert(connected(),"handle not connected to a file");
fits_read_record (FPTR, 0, card, &status);
check_errors();
while (true)
{
fits_find_nextkey (FPTR, const_cast<char **>(inclist), 1,
0, 0, card, &status);
if (status!=0) break;
if (fits_get_keyclass(card)==TYP_USER_KEY)
{
char keyname[80];
int dummy;
fits_get_keyname(card, keyname, &dummy, &status);
check_errors();
keys.push_back(trim(keyname));
}
check_errors();
}
if (status==KEY_NO_EXIST) { fits_clear_errmsg(); status=0; }
check_errors();
}
void fitshandle::set_key_void (const string &key, const void *value,
PDT type, const string &comment)
{
planck_assert(connected(),"handle not connected to a file");
string key2 = fixkey(key);
switch (type)
{
case PLANCK_INT8:
case PLANCK_UINT8:
case PLANCK_INT16:
case PLANCK_INT32:
case PLANCK_INT64:
case PLANCK_FLOAT32:
case PLANCK_FLOAT64:
fits_update_key (FPTR, type2ftc(type), const_cast<char *>(key2.c_str()),
const_cast<void *>(value), const_cast<char *>(comment.c_str()),
&status);
break;
case PLANCK_BOOL:
{
int val = *(static_cast<const bool *>(value));
fits_update_key (FPTR, TLOGICAL, const_cast<char *>(key2.c_str()),
&val, const_cast<char *>(comment.c_str()), &status);
break;
}
case PLANCK_STRING:
{
string val = *(static_cast<const string *>(value));
fits_update_key_longstr (FPTR, const_cast<char *>(key2.c_str()),
const_cast<char *>(val.c_str()), const_cast<char *>(comment.c_str()),
&status);
break;
}
default:
planck_fail ("unsupported data type in set_key_void()");
}
check_errors();
}
void fitshandle::get_key_void (const string &name, void *value, PDT type) const
{
planck_assert(connected(),"handle not connected to a file");
switch (type)
{
case PLANCK_INT8:
case PLANCK_UINT8:
case PLANCK_INT16:
case PLANCK_INT32:
case PLANCK_INT64:
case PLANCK_FLOAT32:
case PLANCK_FLOAT64:
fits_read_key (FPTR, type2ftc(type), const_cast<char *>(name.c_str()),
value, 0, &status);
getKeyHelper(name);
break;
case PLANCK_BOOL:
{
int val;
fits_read_key (FPTR, TLOGICAL, const_cast<char *>(name.c_str()), &val, 0,
&status);
getKeyHelper(name);
*(static_cast<bool *>(value))=val;
break;
}
case PLANCK_STRING:
{
char *tmp=0;
fits_read_key_longstr (FPTR, const_cast<char *>(name.c_str()), &tmp, 0,
&status);
getKeyHelper(name);
*(static_cast<string *>(value))=tmp;
if (tmp) free(tmp);
break;
}
default:
planck_fail ("unsupported data type in get_key_void()");
}
check_errors();
}
void fitshandle::delete_key (const string &name)
{
planck_assert(connected(),"handle not connected to a file");
fits_delete_key (FPTR, const_cast<char *>(name.c_str()), &status);
check_errors();
}
void fitshandle::add_comment(const string &comment)
{
planck_assert(connected(),"handle not connected to a file");
fits_write_comment(FPTR,const_cast<char *>(comment.c_str()),&status);
check_errors();
}
bool fitshandle::key_present(const string &name) const
{
char card[81];
planck_assert(connected(),"handle not connected to a file");
fits_read_card(FPTR, const_cast<char *>(name.c_str()), card, &status);
if (status==KEY_NO_EXIST)
{ fits_clear_errmsg(); status=0; return false; }
check_errors();
return true;
}
void fitshandle::assert_pdmtype (const string &pdmtype) const
{
string type;
get_key("PDMTYPE",type);
if (pdmtype==type) return;
cerr << "PDMTYPE " << pdmtype << " expected, but found " << type << endl;
}
void fitshandle::read_column_raw_void
(int colnum, void *data, PDT type, int64 num, int64 offset) const
{
switch (type)
{
case PLANCK_INT8:
case PLANCK_UINT8:
case PLANCK_INT16:
case PLANCK_INT32:
case PLANCK_INT64:
case PLANCK_FLOAT32:
case PLANCK_FLOAT64:
case PLANCK_BOOL:
read_col (colnum, data, num, type, offset); break;
case PLANCK_STRING:
{
string *data2 = static_cast<string *> (data);
planck_assert(table_hdu(colnum),"incorrect FITS table access");
planck_assert (num<=(nrows_-offset),
"read_column(): array too large");
arr2b<char> tdata(safe_cast<tsize>(num),
safe_cast<tsize>(columns_[colnum-1].repcount()+1));
fits_read_col (FPTR, TSTRING, colnum, offset+1, 1, num,
0, tdata.p0(), 0, &status);
check_errors();
for (long m=0;m<num;++m) data2[m]=tdata[m];
break;
}
default:
planck_fail ("unsupported data type in read_column_raw_void()");
}
}
void fitshandle::write_column_raw_void
(int colnum, const void *data, PDT type, int64 num, int64 offset)
{
switch (type)
{
case PLANCK_INT8:
case PLANCK_UINT8:
case PLANCK_INT16:
case PLANCK_INT32:
case PLANCK_INT64:
case PLANCK_FLOAT32:
case PLANCK_FLOAT64:
case PLANCK_BOOL:
write_col (colnum, data, num, type, offset); break;
case PLANCK_STRING:
{
const string *data2 = static_cast<const string *> (data);
planck_assert(table_hdu(colnum),"incorrect FITS table access");
tsize stringlen = safe_cast<tsize>(columns_[colnum-1].repcount()+1);
arr2b<char> tdata(safe_cast<tsize>(num), stringlen);
for (long m=0;m<num;++m)
{
strncpy(tdata[m],data2[m].c_str(),stringlen-1);
tdata[m][stringlen-1] = '\0';
}
fits_write_col (FPTR, TSTRING, colnum, offset+1, 1, num,
tdata.p0(), &status);
nrows_ = max(nrows_,offset+num);
check_errors();
break;
}
default:
planck_fail ("unsupported data type in write_column_raw_void()");
}
}
void fitshandle::write_image2D_void (const void *data, PDT type, tsize s1,
tsize s2)
{
planck_assert(image_hdu(),"not connected to an image");
planck_assert (axes_.size()==2, "wrong number of dimensions");
planck_assert (axes_[0]==int64(s1), "wrong size of dimension 1");
planck_assert (axes_[1]==int64(s2), "wrong size of dimension 2");
fits_write_img (FPTR, type2ftc(type), 1, axes_[0]*axes_[1],
const_cast<void *>(data), &status);
check_errors();
}
void fitshandle::write_subimage_void (const void *data, PDT type, tsize sz,
int64 offset)
{
planck_assert(image_hdu(),"not connected to an image");
fits_write_img (FPTR, type2ftc(type), 1+offset, sz, const_cast<void *>(data),
&status);
check_errors();
}
template<typename T> void fitshandle::read_image (arr2<T> &data) const
{
planck_assert(image_hdu(),"not connected to an image");
planck_assert (axes_.size()==2, "wrong number of dimensions");
data.alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]));
fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1], 0, &data[0][0], 0,
&status);
check_errors();
}
template void fitshandle::read_image (arr2<float> &data) const;
template void fitshandle::read_image (arr2<double> &data) const;
template<typename T> void fitshandle::read_image (arr3<T> &data) const
{
planck_assert(image_hdu(),"not connected to an image");
planck_assert (axes_.size()==3, "wrong number of dimensions");
data.alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]),
safe_cast<tsize>(axes_[2]));
fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1]*axes_[2],
0, &data(0,0,0), 0, &status);
check_errors();
}
template void fitshandle::read_image (arr3<float> &data) const;
template void fitshandle::read_image (arr3<double> &data) const;
template<typename T> void fitshandle::read_subimage
(arr2<T> &data, int xl, int yl) const
{
planck_assert(image_hdu(),"not connected to an image");
planck_assert (axes_.size()==2, "wrong number of dimensions");
for (tsize m=0; m<data.size1(); ++m)
fits_read_img (FPTR, fitsType<T>(), (xl+m)*axes_[1]+yl+1,
data.size2(), 0, &data[m][0], 0, &status);
check_errors();
}
template void fitshandle::read_subimage
(arr2<float> &data, int xl, int yl) const;
template void fitshandle::read_subimage
(arr2<double> &data, int xl, int yl) const;
void fitshandle::read_subimage_void (void *data, PDT type, tsize ndata,
int64 offset) const
{
planck_assert(image_hdu(),"not connected to an image");
fits_read_img (FPTR, type2ftc(type), 1+offset, ndata, 0, data, 0, &status);
check_errors();
}
namespace {
class cfitsio_checker
{
public:
cfitsio_checker()
{
float fitsversion;
planck_assert(fits_get_version(&fitsversion),
"error calling fits_get_version()");
int v_header = nearest<int>(1000.*CFITSIO_VERSION),
v_library = nearest<int>(1000.*fitsversion);
if (v_header!=v_library)
cerr << endl << "WARNING: version mismatch between CFITSIO header (v"
<< dataToString(v_header*0.001) << ") and linked library (v"
<< dataToString(v_library*0.001) << ")." << endl << endl;
}
};
cfitsio_checker Cfitsio_Checker;
} // unnamed namespace

301
external/healpix/cxxsupport/fitshandle.h vendored Normal file
View file

@ -0,0 +1,301 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file fitshandle.h
* Declaration of the FITS I/O helper class used by LevelS
*
* Copyright (C) 2002 - 2009 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_FITSHANDLE_H
#define PLANCK_FITSHANDLE_H
#include <string>
#include <vector>
#include "arr.h"
#include "datatypes.h"
#include "safe_cast.h"
/*! \defgroup fitsgroup FITS-related functionality */
/*! \{ */
/*! Class containing information about a single column in a FITS table. */
class fitscolumn
{
private:
std::string name_, unit_;
int64 repcount_;
PDT type_;
public:
fitscolumn();
/*! Creates a \a fitscolumn with name \a nm, unit \a un, a repetition
count of \a rc, and a Planck type of \a tp. */
fitscolumn (const std::string &nm, const std::string &un, int64 rc, PDT tp);
/*! Returns the column name. */
const std::string &name() const {return name_;}
/*! Returns the column unit string. */
const std::string &unit() const {return unit_;}
/*! Returns the repetition count of the column. */
int64 repcount() const {return repcount_;}
/*! Returns the Planck type of the column. */
PDT type() const {return type_;}
};
/*! Class for performing I/O from/to FITS files. */
class fitshandle
{
private:
enum { INVALID = -4711 };
mutable int status;
void *fptr;
int hdutype_, bitpix_;
std::vector<int64> axes_;
std::vector<fitscolumn> columns_;
int64 nrows_;
void check_errors() const;
void clean_data();
void clean_all();
bool connected() const { return (hdutype_!=INVALID); }
bool table_hdu (tsize col) const;
bool image_hdu () const;
void init_image();
void init_asciitab();
void init_bintab();
void init_data();
void read_col (int colnum, void *data, int64 ndata, PDT type,
int64 offset) const;
void write_col (int colnum, const void *data, int64 ndata, PDT type,
int64 offset);
void getKeyHelper(const std::string &name) const;
public:
/*! the list of modes in which a \a fitshandle can be opened. */
enum openmethod { CREATE, /*!< the file must not yet exist */
OPEN /*!< the file must already exist */
};
/*! \name File-level access and manipulation. */
/*! \{ */
/*! Creates an unconnected \a fitshandle. */
fitshandle ()
: status(0), fptr(0), hdutype_(INVALID), bitpix_(INVALID), nrows_(0) {}
/*! Performs all necessary cleanups. */
~fitshandle() { clean_all(); }
/*! Connects to the file \a fname. */
void open (const std::string &fname);
/*! Creates the file \a fname and connects to it. */
void create (const std::string &fname);
/*! Closes the current file. */
void close () { clean_all(); }
/*! Deletes the file with name \a name. */
static void delete_file (const std::string &name);
/*! Jumps to the HDU with the absolute number \a hdu. */
void goto_hdu (int hdu);
/*! Returns the number of HDUs in the file. */
int num_hdus () const;
/*! Asserts that the PDMTYPE of the current HDU is \a pdmtype. */
void assert_pdmtype (const std::string &pdmtype) const;
/*! Inserts a binary table described by \a cols.
The HDU has the name \a extname. */
void insert_bintab (const std::vector<fitscolumn> &cols,
const std::string &extname="xtension");
/*! Inserts an ASCII table described by \a cols. The width of the
columns is chosen automatically, in a way that avoids truncation.
The HDU has the name \a extname. */
void insert_asctab (const std::vector<fitscolumn> &cols,
const std::string &extname="xtension");
/*! Inserts a FITS image with the type given by \a type and dimensions
given by \a Axes. */
void insert_image (PDT type, const std::vector<int64> &Axes);
/*! Inserts a 2D FITS image with the type given by \a type, whose
contents are given in \a data. */
template<typename T>
void insert_image (PDT type, const arr2<T> &data);
/*! Computes the checksum for the current HDU and writes it into the
header. */
void write_checksum();
/*! \} */
/*! \name Information about the current HDU */
/*! \{ */
/*! Returns the dimensions of the current image. */
const std::vector<int64> &axes() const;
/*! Returns the name of column \a #i. */
const std::string &colname(int i) const;
/*! Returns the unit of column \a #i. */
const std::string &colunit(int i) const;
/*! Returns repetition count of column \a #i. */
int64 repcount(int i) const;
/*! Returns the Planck type for column \a #i. */
PDT coltype(int i) const;
/*! Returns the number of columns in the current table. */
int ncols() const;
/*! Returns the number of rows in the current table. */
int64 nrows() const;
/*! Returns the total number of elements (nrows*repcount)
in column \a #i. */
int64 nelems(int i) const;
/*! Returns the number of elements that should be read/written in a single
call for optimum performance. This depends on the current HDU. */
int64 efficientChunkSize(int i) const;
/*! \} */
/*! \name Keyword-handling methods */
/*! \{ */
/*! Returns a list of all user-defined keys in the current HDU
in \a keys. */
void get_all_keys (std::vector<std::string> &keys) const;
void set_key_void (const std::string &key, const void *value, PDT type,
const std::string &comment="");
/*! Updates \a key with \a value and \a comment. */
template<typename T> void set_key (const std::string &name,
const T &value, const std::string &comment="")
{ set_key_void (name, &value, planckType<T>(), comment); }
/*! Deletes \a key from the header. */
void delete_key (const std::string &name);
/*! Adds \a comment as a comment line. */
void add_comment (const std::string &comment);
void get_key_void (const std::string &key, void *value, PDT type) const;
/*! Reads the value belonging to \a key and returns it in \a value. */
template<typename T> void get_key (const std::string &name, T &value) const
{ get_key_void (name,&value,planckType<T>()); }
/*! Returms the value belonging to \a key. */
template<typename T> T get_key (const std::string &name) const
{ T tmp; get_key(name, tmp); return tmp; }
/*! Returns \a true if \a key is present, else \a false. */
bool key_present (const std::string &name) const;
/*! \} */
/*! \name Methods for table data I/O */
/*! \{ */
void read_column_raw_void
(int colnum, void *data, PDT type, int64 num, int64 offset=0) const;
/*! Copies \a num elements from column \a colnum to the memory pointed
to by \a data, starting at offset \a offset in the column. */
template<typename T> void read_column_raw
(int colnum, T *data, int64 num, int64 offset=0) const
{ read_column_raw_void (colnum, data, planckType<T>(), num, offset); }
/*! Fills \a data with elements from column \a colnum,
starting at offset \a offset in the column. */
template<typename T> void read_column
(int colnum, arr<T> &data, int64 offset=0) const
{ read_column_raw (colnum, &(data[0]), data.size(), offset); }
/*! Reads the element \a #offset from column \a colnum into \a data. */
template<typename T> void read_column
(int colnum, T &data, int64 offset=0) const
{ read_column_raw (colnum, &data, 1, offset); }
/*! Reads the whole column \a colnum into \a data (which is resized
accordingly). */
template<typename T> void read_entire_column
(int colnum, arr<T> &data) const
{
data.alloc(safe_cast<tsize>(nelems(colnum)));
read_column (colnum, data);
}
void write_column_raw_void
(int colnum, const void *data, PDT type, int64 num, int64 offset=0);
/*! Copies \a num elements from the memory pointed to by \a data to the
column \a colnum, starting at offset \a offset in the column. */
template<typename T> void write_column_raw
(int colnum, const T *data, int64 num, int64 offset=0)
{ write_column_raw_void (colnum, data, planckType<T>(), num, offset); }
/*! Copies all elements from \a data to the
column \a colnum, starting at offset \a offset in the column. */
template<typename T> void write_column
(int colnum, const arr<T> &data, int64 offset=0)
{ write_column_raw (colnum, &(data[0]), data.size(), offset); }
/*! Copies \a data to the column \a colnum, at the position \a offset. */
template<typename T> void write_column
(int colnum, const T &data, int64 offset=0)
{ write_column_raw (colnum, &data, 1, offset); }
/*! \} */
/*! \name Methods for image data I/O */
/*! \{ */
/*! Reads the current image into \a data, which is resized accordingly. */
template<typename T> void read_image (arr2<T> &data) const;
/*! Reads the current image into \a data, which is resized accordingly. */
template<typename T> void read_image (arr3<T> &data) const;
/*! Reads a partial image, whose dimensions are given by the dimensions
of \a data, into data. The starting pixel indices are given by
\a xl and \a yl. */
template<typename T> void read_subimage
(arr2<T> &data, int xl, int yl) const;
void read_subimage_void (void *data, PDT type, tsize ndata, int64 offset=0)
const;
/*! Fills \a data with values from the image, starting at the offset
\a offset in the image. The image is treated as a one-dimensional
array. */
template<typename T> void read_subimage (arr<T> &data, int64 offset=0)
const
{ read_subimage_void (&data[0],planckType<T>(),data.size(),offset); }
void write_image2D_void (const void *data, PDT type, tsize s1,
tsize s2);
/*! Writes \a data into the current image. \a data must have the same
dimensions as specified in the HDU. */
template<typename T> void write_image (const arr2<T> &data)
{
write_image2D_void (&data[0][0],planckType<T>(),data.size1(),
data.size2());
}
void write_subimage_void (const void *data, PDT type, tsize sz,
int64 offset);
/*! Copies \a data to the image, starting at the offset
\a offset in the image. The image is treated as a one-dimensional
array. */
template<typename T> void write_subimage (const arr<T> &data,
int64 offset=0)
{ write_subimage_void(&data[0],planckType<T>(),data.size(),offset); }
/*! \} */
};
/*! \} */
#endif

3848
external/healpix/cxxsupport/font_data.inc vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file geom_utils.h
* Geometric utility functions.
*
* Copyright (C) 2003, 2006 Max-Planck-Society
* \author Martin Reinecke
* \author Reinhard Hell
*/
#ifndef PLANCK_GEOM_UTILS_H
#define PLANCK_GEOM_UTILS_H
#include "cxxutils.h"
#include "vec3.h"
/*! Returns the orientation when looking from point \a loc on the unit
sphere in the direction \a dir. \a loc must be normalized. The result
ranges from -pi to pi, is 0 for North and pi/2 for West, i.e. the angle
is given in mathematically positive sense.
If \a loc is the North or South pole, the returned angle is
\a atan2(dir.y,dir.x). */
inline double orientation (const vec3 &loc, const vec3 &dir)
{
// FIXME: here is still optimization potential
if (loc.x==0 && loc.y==0)
return (loc.z>0) ? safe_atan2(dir.y,-dir.x) : safe_atan2(dir.y,dir.x);
vec3 east (-loc.y, loc.x, 0);
vec3 north = crossprod(loc,east);
return safe_atan2(-dotprod(dir,east),dotprod(dir,north));
}
/*! Returns the angle between \a v1 and \a v2 in radians. */
inline double v_angle (const vec3 &v1, const vec3 &v2)
{ return atan2 (crossprod(v1,v2).Length(), dotprod(v1,v2)); }
#endif

View file

@ -0,0 +1,15 @@
#ifndef LEVELS_FACILITIES_H
#define LEVELS_FACILITIES_H
int syn_alm_cxx_module (int argc, const char **argv);
int alm2map_cxx_module (int argc, const char **argv);
int anafast_cxx_module (int argc, const char **argv);
int calc_powspec_module (int argc, const char **argv);
int hotspots_cxx_module (int argc, const char **argv);
int map2tga_module (int argc, const char **argv);
int median_filter_cxx_module (int argc, const char **argv);
int mult_alm_module (int argc, const char **argv);
int smoothing_cxx_module (int argc, const char **argv);
int udgrade_cxx_module (int argc, const char **argv);
#endif

219
external/healpix/cxxsupport/ls_image.cc vendored Normal file
View file

@ -0,0 +1,219 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Classes for creation and output of image files
*
* Copyright (C) 2003 Max-Planck-Society
* Author: Martin Reinecke
*/
#include <fstream>
#include <sstream>
#include "ls_image.h"
#include "bstream.h"
#include "font_data.inc"
using namespace std;
const Font medium_bold_font = { 0, 128, 7, 13, medium_bold_font_data };
const Font giant_font = { 0, 128, 9, 15, giant_font_data };
void Palette::setPredefined (int num)
{
fv.clear(); cv.clear();
switch(num)
{
case 0:
add(0,Colour(0,0,0));
add(1,Colour(1,1,1));
break;
case 1:
add(0,Colour(0,0,0));
add(0.4f,Colour(0,0,0.5f));
add(0.75f,Colour(0,0.6f,1));
add(1,Colour(1,1,1));
break;
case 4:
add(0,Colour(0,0,.5f));
add(0.15f,Colour(0,0,1));
add(0.4f,Colour(0,1,1));
add(0.7f,Colour(1,1,0));
add(0.9f,Colour(1,.33f,0));
add(1,Colour(.5f,0,0));
break;
default:
planck_fail("Palette #"+dataToString(num)+" not yet supported.");
}
}
void LS_Image::write_char (int xpos, int ypos, const Colour &col, char c,
int scale)
{
planck_assert ((c>=font.offset) && (c<font.offset+font.num_chars),
"write_char: character out of range");
for (int i=0; i<font.xpix; ++i)
for (int j=0; j<font.ypix; ++j)
{
int ofs = (c-font.offset)*font.xpix*font.ypix + j*font.xpix + i;
if (font.data[ofs]!=' ')
for (int m=0; m<scale; ++m)
for (int n=0; n<scale; ++n)
put_pixel(xpos+scale*i+m,ypos+scale*j+n,col);
}
}
LS_Image::LS_Image ()
: font(medium_bold_font) {}
LS_Image::LS_Image (int xres, int yres)
: font(medium_bold_font), pixel(xres,yres,Colour(0,0,0)) {}
void LS_Image::annotate (int xpos, int ypos, const Colour &col,
const string &text, int scale)
{
for (tsize m=0; m<text.length(); ++m)
write_char(xpos+m*scale*font.xpix, ypos, col, text[m],scale);
}
void LS_Image::annotate_centered (int xpos, int ypos, const Colour &col,
const string &text, int scale)
{
xpos-=(scale*text.length()*font.xpix)/2;
ypos-=scale*font.ypix/2;
annotate (xpos,ypos,col,text,scale);
}
void LS_Image::set_font (const Font &fnt)
{ font = fnt; }
void LS_Image::write_TGA (const string &file) const
{
ofstream out(file.c_str(), ios_base::out | ios_base::binary);
planck_assert(out, "could not create file '" + file + "'");
tsize xres=pixel.size1(), yres=pixel.size2();
bostream bo(out);
const uint8 header[18] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
uint8(xres%256), uint8(xres/256), uint8(yres%256), uint8(yres/256), 24, 32};
bo.put (header, 18);
for (tsize j=0; j<yres; ++j)
for (tsize i=0; i<xres; ++i)
bo << pixel[i][j].b << pixel[i][j].g << pixel[i][j].r;
}
namespace {
void write_equal_range (const arr<Colour8> &px, tsize begin, tsize end,
bostream &file)
{
chunkMaker cm (end-begin,128);
uint64 cbeg, csz;
while (cm.getNext(cbeg,csz))
{
file << uint8(csz-1+128);
file << px[begin].b << px[begin].g << px[begin].r;
}
}
void write_unequal_range (const arr<Colour8> &px, tsize begin, tsize end,
bostream &file)
{
chunkMaker cm (end-begin,128);
uint64 cbeg, csz;
while (cm.getNext(cbeg,csz))
{
file << uint8(csz-1);
for (tsize cnt=begin+cbeg; cnt< begin+cbeg+csz; ++cnt)
file << px[cnt].b << px[cnt].g << px[cnt].r;
}
}
} // unnamed namespace
void LS_Image::write_TGA_rle(const string &file) const
{
ofstream out(file.c_str(), ios_base::out | ios_base::binary);
planck_assert(out, "could not create file '" + file + "'");
tsize xres=pixel.size1(), yres=pixel.size2();
bostream bo(out);
const uint8 header[18] = { 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
xres%256, xres/256, yres%256, yres/256, 24, 32 };
bo.put(header,18);
for (tsize y=0; y<yres; ++y)
{
arr<Colour8> px(xres);
for (tsize x=0; x<xres; ++x) px[x] = pixel[x][y];
tsize xstart=0;
while (xstart<xres)
{
if (xstart==xres-1)
{
write_unequal_range (px,xstart,xstart+1,bo);
xstart=xres;
}
else
{
if (px[xstart+1]==px[xstart]) // range of equal pixels
{
tsize xend=xstart+2;
while ((xend<xres) && (px[xend]==px[xstart])) ++xend;
write_equal_range (px,xstart,xend,bo);
xstart=xend;
}
else
{
tsize xend=xstart+2;
while ((xend<xres) && (px[xend]!=px[xend-1])) ++xend;
write_unequal_range (px,xstart,xend,bo);
xstart=xend;
}
}
}
}
}
void LS_Image::write_PPM (const string &file) const
{
ofstream out(file.c_str(), ios_base::out | ios_base::binary);
planck_assert(out, "could not create file '" + file + "'");
tsize xres=pixel.size1(), yres=pixel.size2();
bostream bo(out);
ostringstream header;
header << "P6" << endl << xres << endl << yres << endl << 255 << endl;
string hdrdata = header.str();
bo.put(hdrdata.c_str(),hdrdata.size());
for (tsize j=0; j<yres; ++j)
for (tsize i=0; i<xres; ++i)
bo << pixel[i][j].r << pixel[i][j].g << pixel[i][j].b;
}

192
external/healpix/cxxsupport/ls_image.h vendored Normal file
View file

@ -0,0 +1,192 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file ls_image.h
* Classes for creation and output of image files
*
* Copyright (C) 2003-2010 Max-Planck-Society
* \author Martin Reinecke, David Larson
*/
#ifndef PLANCK_LS_IMAGE_H
#define PLANCK_LS_IMAGE_H
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include "arr.h"
#include "datatypes.h"
/*! \defgroup imagegroup Image creation */
/*! \{ */
/*! A very simple class for storing RGB colours. */
class Colour
{
public:
float r, /*!< the red component */
g, /*!< the green component */
b; /*!< the blue component */
/*! Default constructor. Does not initialize \a r, \a g and \a b. */
Colour() {}
/*! Initializes the colour with \a R, \a G and \a B. */
Colour (float R, float G, float B) : r(R), g(G), b(B) {}
/*! Multiplies all components with \a fact. */
const Colour &operator*= (float fact)
{ r*=fact; g*=fact; b*=fact; return *this; }
/*! Returns the sum colour of \a *this and \a c2. */
const Colour operator+ (const Colour &c2) const
{ return Colour(r+c2.r, g+c2.g, b+c2.b); }
/*! Returns \a *this, scaled by \a f. */
const Colour operator* (double f) const
{ return Colour(float(r*f), float(g*f), float(b*f)); }
};
/*! A class for mapping floting-point values into colours. */
class Palette
{
private:
std::vector<Colour> cv;
std::vector<float> fv;
public:
/*! Adds a new data point \a f, with the corresponding colour \a c.
The additions must be done in the order of ascending \a f. */
void add (float f, const Colour &c)
{
fv.push_back(f);
cv.push_back(c);
}
/*! Sets the palette to the predefined palette \a num. */
void setPredefined(int num);
/*! Returns the colour corresponding to the value \a f. The colour is
determined by linear interpolation between neighbouring data points. */
Colour Get_Colour (float f) const
{
if (f<=fv[0]) return cv[0];
if (f>=fv[fv.size()-1]) return cv[cv.size()-1];
int i=0;
while (f>fv[i]) ++i;
return cv[i-1]*((fv[i]-f)/(fv[i]-fv[i-1]))
+ cv[i]*((f-fv[i-1])/(fv[i]-fv[i-1]));
}
};
class Colour8
{
private:
void import (const Colour &col)
{
using namespace std;
r = uint8(max(0,min(255,int(col.r*256))));
g = uint8(max(0,min(255,int(col.g*256))));
b = uint8(max(0,min(255,int(col.b*256))));
}
public:
uint8 r,g,b;
Colour8() {}
Colour8 (uint8 R, uint8 G, uint8 B)
: r(R), g(G), b(B) {}
Colour8 (const Colour &col)
{ import (col); }
const Colour8 &operator= (const Colour &col)
{ import (col); return *this; }
bool operator== (const Colour8 &that)
{ return (r == that.r) && (g == that.g) && (b == that.b); }
bool operator!= (const Colour8 &that)
{ return (r != that.r) || (g != that.g) || (b != that.b); }
};
class Font
{
public:
int offset, num_chars, xpix, ypix;
const char *data;
};
extern const Font medium_bold_font;
extern const Font giant_font;
/*! Class for creating and storing image files. */
class LS_Image
{
private:
Font font;
arr2<Colour8> pixel;
void write_char (int xpos, int ypos, const Colour &col, char c,
int scale=1);
public:
/*! */
LS_Image ();
/*! Creates an image object with a resolution of \a xres by \a yres. */
LS_Image (int xres, int yres);
/*! */
~LS_Image () {}
/*! Fills the entire image with colour \a col. */
void fill (const Colour &col) { pixel.fill(col); }
/*! Sets the font used for annotations to \a fnt. */
void set_font (const Font &fnt);
/*! Outputs the string \a text in colour \a col.
\a xpos, \a ypos is the lower left corner;
the font is scaled by \a scale. */
void annotate (int xpos, int ypos, const Colour &col,
const std::string &text, int scale=1);
/*! Outputs the string \a text centered at position \a xpos, \a ypos
in colour \a col. The font is scaled by \a scale. */
void annotate_centered (int xpos, int ypos, const Colour &col,
const std::string &text, int scale=1);
/*! Sets the pixel \a i, \a j, to the colour \a col. */
void put_pixel (tsize i, tsize j, const Colour &col)
{
if ((i<pixel.size1()) && (j<pixel.size2()))
pixel[i][j] = col;
}
/*! Returns the colour of the pixel \a i, \a j, or black if the pixel
lies outside of the image. */
Colour8 get_pixel (tsize i, tsize j)
{
return ((i<pixel.size1()) && (j<pixel.size2())) ?
pixel[i][j] : Colour8(0, 0, 0);
}
/*! Writes the image to \a file in uncompressed TGA format. */
void write_TGA (const std::string &file) const;
/*! Writes the image to \a file in run-length encoded TGA format. */
void write_TGA_rle (const std::string &file) const;
/*! Writes the image to \a file in binary PPM format. */
void write_PPM (const std::string &file) const;
};
/*! \} */
#endif

View file

@ -0,0 +1,93 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file lsconstants.h
* Mathematical, physical and technical constants for LevelS.
*/
#ifndef PLANCK_CONSTANTS_H
#define PLANCK_CONSTANTS_H
/*! \defgroup mathconstgroup Mathematical constants */
/*! \{ */
const double pi=3.141592653589793238462643383279502884197;
const double twopi=6.283185307179586476925286766559005768394;
const double inv_twopi=1.0/twopi;
const double fourpi=12.56637061435917295385057353311801153679;
const double halfpi=1.570796326794896619231321691639751442099;
const double inv_halfpi=0.6366197723675813430755350534900574;
const double inv_sqrt4pi = 0.2820947917738781434740397257803862929220;
const double ln2 = 0.6931471805599453094172321214581766;
const double inv_ln2 = 1.4426950408889634073599246810018921;
const double ln10 = 2.3025850929940456840179914546843642;
const double onethird=1.0/3.0;
const double twothird=2.0/3.0;
const double fourthird=4.0/3.0;
const double degr2rad=pi/180.0;
const double arcmin2rad=degr2rad/60;
const double rad2degr=180.0/pi;
//! Ratio between FWHM and sigma of a Gauss curve (\f$\sqrt{8\ln2}\f$).
const double sigma2fwhm=2.3548200450309493; // sqrt(8*log(2.))
const double fwhm2sigma=1/sigma2fwhm;
/*! \} */
/*! \defgroup physconstgroup Physical constants */
/*! \{ */
const double Jansky2SI=1.0e-26;
const double SI2Jansky=1.0e+26;
//! Light speed in m/s (CODATA 2006)
const double speedOfLight=2.99792458e8;
//! Boltzmann's constant in J/K (CODATA 2006)
const double kBoltzmann=1.3806504e-23;
//! Stefan-Boltzmann constant in W/m^2/K^4 (CODATA 2006)
const double sigmaStefanBoltzmann=5.6704e-8;
//! Planck's constant in J s (CODATA 2006)
const double hPlanck=6.62606896e-34;
//! Astronomical unit in m
const double astronomicalUnit=1.49597870691e11;
//! Solar constant in W/m^2
const double solarConstant=1368.0;
//! Average CMB temperature in K (Mather et al. 1999, ApJ 512, 511)
const double tcmb = 2.725;
//! offset (in seconds) between Jan 1, 1958 and Jan 1, 1970
const double sec_58_70 = 378691200.;
/*! \} */
#endif

View file

@ -0,0 +1,89 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Copyright (C) 2005, 2006, 2007, 2009, 2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_OPENMP_SUPPORT_H
#define PLANCK_OPENMP_SUPPORT_H
#ifdef _OPENMP
#include <omp.h>
#endif
#include "cxxutils.h"
inline bool openmp_enabled()
{
#ifdef _OPENMP
return true;
#else
return false;
#endif
}
inline int openmp_max_threads ()
{
#ifdef _OPENMP
return omp_get_max_threads();
#else
return 1;
#endif
}
inline int openmp_num_threads ()
{
#ifdef _OPENMP
return omp_get_num_threads();
#else
return 1;
#endif
}
inline int openmp_thread_num ()
{
#ifdef _OPENMP
return omp_get_thread_num();
#else
return 0;
#endif
}
/*! Calculates the range of indices between \a glo and \a ghi which
must be processed by this thread and returns it in \a lo and \a hi.
The indices \a ghi and \a hi are "one past the last real index",
in analogy to the STL iterators. */
inline void openmp_calc_share (int64 glo, int64 ghi, int64 &lo, int64 &hi)
{
#ifdef _OPENMP
calcShareGeneral (glo,ghi,omp_get_num_threads(),omp_get_thread_num(),lo,hi);
#else
lo=glo; hi=ghi;
#endif
}
#endif

116
external/healpix/cxxsupport/paramfile.h vendored Normal file
View file

@ -0,0 +1,116 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Class for parsing parameter files
*
* Copyright (C) 2003, 2004, 2005, 2008, 2009, 2010 Max-Planck-Society
* Authors: Martin Reinecke, Reinhard Hell
*/
#ifndef PLANCK_PARAMFILE_H
#define PLANCK_PARAMFILE_H
#include <map>
#include <set>
#include <string>
#include <iostream>
#include "cxxutils.h"
class paramfile
{
private:
typedef std::map<std::string,std::string> params_type;
params_type params;
mutable std::set<std::string> read_params;
bool verbose;
std::string get_valstr(const std::string &key) const
{
params_type::const_iterator loc=params.find(key);
if (loc!=params.end()) return loc->second;
planck_fail ("Cannot find the key '" + key + "'.");
}
bool param_unread (const std::string &key) const
{ return (read_params.find(key)==read_params.end()); }
public:
paramfile (const std::string &filename, bool verbose_=true)
: verbose(verbose_)
{ parse_file (filename, params); }
paramfile (const params_type &par, bool verbose_=true)
: params (par), verbose(verbose_)
{}
~paramfile ()
{
if (verbose)
for (params_type::const_iterator loc=params.begin();
loc!=params.end(); ++loc)
if (param_unread(loc->first))
std::cout << "Parser warning: unused parameter '"
<< loc->first << "'" << std::endl;
}
void setVerbosity (bool verbose_)
{ verbose = verbose_; }
bool getVerbosity () const
{ return verbose; }
bool param_present(const std::string &key) const
{ return (params.find(key)!=params.end()); }
template<typename T> T find (const std::string &key) const
{
T result;
stringToData(get_valstr(key),result);
std::string output = dataToString(result);
if (planckType<T>()==PLANCK_STRING) output = "'"+output+"'";
if (verbose && param_unread(key))
std::cout << "Parser: " << key << " = " << output << std::endl;
read_params.insert(key);
return result;
}
template<typename T> T find
(const std::string &key, const T &deflt)
{
if (param_present(key)) return find<T>(key);
std::string output = dataToString(deflt);
if (planckType<T>()==PLANCK_STRING) output = "'"+output+"'";
if (verbose && param_unread(key))
std::cout << "Parser: " << key << " = " << output
<< " <default>" << std::endl;
params[key]=dataToString(deflt);
read_params.insert(key);
return deflt;
}
const params_type &getParams() const
{ return params; }
};
#endif

22
external/healpix/cxxsupport/planck.make vendored Normal file
View file

@ -0,0 +1,22 @@
PKG:=cxxsupport
SD:=$(SRCROOT)/$(PKG)
OD:=$(BLDROOT)/$(PKG)
FULL_INCLUDE+= -I$(SD)
HDR_$(PKG):=$(SD)/*.h
LIB_$(PKG):=$(LIBDIR)/libcxxsupport.a
OBJ:=cxxutils.o fitshandle.o rotmatrix.o trafos.o ls_image.o error_handling.o wigner.o
OBJ:=$(OBJ:%=$(OD)/%)
ODEP:=$(HDR_$(PKG)) $(HDR_libfftpack) $(HDR_c_utils)
$(OBJ): $(ODEP) | $(OD)_mkdir
$(LIB_$(PKG)): $(OBJ)
$(OD)/fitshandle.o: $(HDR_libcfitsio)
$(OD)/ls_image.o: $(SD)/font_data.inc
all_hdr+=$(HDR_$(PKG))
all_lib+=$(LIB_$(PKG))

154
external/healpix/cxxsupport/planck_rng.h vendored Normal file
View file

@ -0,0 +1,154 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file planck_rng.h
* This file contains the random number generator
* used by the Planck LevelS package.
* The generator is a C++ port of the xorshift generator xor128() described
* in Marsaglia, Journal of Statistical Software 2003, vol 8.
* It has a period of 2^128 - 1.
*
* Copyright (C) 2003, 2004, 2005 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_RNG_H
#define PLANCK_RNG_H
#include <cmath>
#include "error_handling.h"
/*! C++ port of the xorshift generator xor128() described in Marsaglia,
Journal of Statistical Software 2003, vol 8.
It has a period of 2^128 - 1. */
class planck_rng
{
private:
unsigned int x,y,z,w;
double small, gset;
bool empty;
void twiddle (unsigned int &v)
{
for (int i=0; i<9; ++i)
{
v ^= v<<13;
v ^= v>>17;
v ^= v<<5;
}
}
void init_rng ()
{
// avoid zero seeds
if (x==0) x = 123456789;
if (y==0) y = 362436069;
if (z==0) z = 521288629;
if (w==0) w = 88675123;
// shuffle the bits of the seeds
twiddle(x); twiddle(y); twiddle(z); twiddle(w);
// burn in the RNG
for (int i=0; i<16; ++i)
int_rand_uni();
}
public:
/*! Initializes the generator with 0 to 4 seed values. */
planck_rng (unsigned int x1=123456789, unsigned int y1=362436069,
unsigned int z1=521288629, unsigned int w1=88675123)
: x(x1), y(y1), z(z1), w(w1),
small(1./(1.+double(0xFFFFFFFF))), gset(0.), empty(true)
{
planck_assert (sizeof(unsigned int)==4, "wrong integer size for RNG");
init_rng();
}
/*! Re-initializes the generator with 0 to 4 seed values. */
void seed (unsigned int x1=123456789, unsigned int y1=362436069,
unsigned int z1=521288629, unsigned int w1=88675123)
{
x = x1; y = y1; z = z1; w = w1;
empty = true;
init_rng();
}
/*! Returns uniformly distributed random integer numbers from the
interval [0;0xFFFFFFFF]. */
unsigned int int_rand_uni()
{
unsigned int t = x^(x<<11);
x = y;
y = z;
z = w;
return w=(w^(w>>19))^(t^(t>>8));
}
//! Returns uniformly distributed random numbers from the interval [0;1[.
double rand_uni()
{
return small*int_rand_uni();
}
//! Returns random numbers with Gaussian distribution (mean=0, sigma=1).
/*! Uses rand_uni() internally. */
double rand_gauss()
{
using namespace std;
if (empty)
{
double v1,v2,rsq;
do
{
v1=2*rand_uni()-1.;
v2=2*rand_uni()-1.;
rsq=v1*v1+v2*v2;
}
while ((rsq>=1) || (rsq==0));
double fac=sqrt(-2*log(rsq)/rsq);
gset=v1*fac;
empty=false;
return v2*fac;
}
else
{
empty=true;
return gset;
}
}
//! Returns exponentially distributed random numbers (mean=1, nonnegative)
/*! Uses rand_uni() internally. */
double rand_exp()
{
using namespace std;
double val=rand_uni();
if (val==0.) val=1.;
return -log(val);
}
};
#endif

106
external/healpix/cxxsupport/pointing.h vendored Normal file
View file

@ -0,0 +1,106 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file pointing.h
* Class representing a direction in 3D space
*
* Copyright (C) 2003-2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_POINTING_H
#define PLANCK_POINTING_H
#include <cmath>
#include "vec3.h"
#include "cxxutils.h"
/*! \defgroup pointinggroup Pointings */
/*! \{ */
/*! Class representing a direction in 3D space or a location on the
unit sphere. All angles in radians. */
class pointing
{
public:
/*! Colatitude of the pointing (i.e. the North pole is at \a theta=0). */
double theta;
/*! Longitude of the pointing. */
double phi;
/*! Default constructor. \a theta and \a phi are not initialized. */
pointing() {}
/*! Creates a pointing with \a Theta and \a Phi. */
pointing (double Theta, double Phi) : theta(Theta), phi(Phi) {}
// FIXME: should become "explicit" some time
/*! Creates a pointing from the vector \a inp. \a inp need not be
normalized. */
pointing (const vec3 &inp)
{ from_vec3(inp); }
// FIXME: should be removed some time
/*! Returns a normalized vector pointing in the same direction. */
operator vec3() const
{ return to_vec3(); }
/*! Returns a normalized vector pointing in the same direction. */
vec3 to_vec3() const
{
double st=sin(theta);
return vec3 (st*cos(phi), st*sin(phi), cos(theta));
}
/*! Converts \a inp to \a ptg. \a inp need not be normalized. */
void from_vec3 (const vec3 &inp)
{
using namespace std;
const double twopi_=6.283185307179586476925286766559005768394;
theta = atan2(sqrt(inp.x*inp.x+inp.y*inp.y),inp.z);
phi = safe_atan2 (inp.y,inp.x);
if (phi<0.) phi += twopi_;
}
/*! Changes the angles so that \a 0<=theta<=pi and \a 0<=phi<2*pi. */
void normalize()
{
const double pi_=3.141592653589793238462643383279502884197;
const double twopi_=6.283185307179586476925286766559005768394;
theta=fmodulo(theta,twopi_);
if (theta>pi_)
{
phi+=pi_;
theta=twopi_-theta;
}
phi=fmodulo(phi,twopi_);
}
};
/*! Writes \a p to \a os.
\relates pointing */
inline std::ostream &operator<< (std::ostream &os, const pointing &p)
{
os << p.theta << ", " << p.phi << std::endl;
return os;
}
/*! \} */
#endif

177
external/healpix/cxxsupport/rotmatrix.cc vendored Normal file
View file

@ -0,0 +1,177 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*
* Class for rotation transforms in 3D space
*
* Copyright (C) 2003 Max-Planck-Society
* Author: Martin Reinecke
*/
#include "rotmatrix.h"
#include "vec3.h"
#include "lsconstants.h"
#include <algorithm>
using namespace std;
rotmatrix::rotmatrix (const vec3 &a, const vec3 &b, const vec3 &c)
{
entry[0][0]=a.x; entry[0][1]=b.x; entry[0][2]=c.x;
entry[1][0]=a.y; entry[1][1]=b.y; entry[1][2]=c.y;
entry[2][0]=a.z; entry[2][1]=b.z; entry[2][2]=c.z;
}
void rotmatrix::SetToIdentity ()
{
entry[0][0] = entry[1][1] = entry[2][2] = 1.;
entry[0][1] = entry[1][0] = entry[0][2] =
entry[2][0] = entry[1][2] = entry[2][1] = 0.;
}
void rotmatrix::SetToZero ()
{
for (int m=0; m<3; ++m)
entry[m][0] = entry[m][1] = entry[m][2] = 0;
}
void rotmatrix::Transpose ()
{
swap(entry[0][1], entry[1][0]);
swap(entry[0][2], entry[2][0]);
swap(entry[1][2], entry[2][1]);
}
void rotmatrix::toAxisAngle (vec3 &axis, double &angle) const
{
double c2 = entry[0][0] + entry[1][1] + entry[2][2] - 1;
axis.x = entry[2][1] - entry[1][2];
axis.y = entry[0][2] - entry[2][0];
axis.z = entry[1][0] - entry[0][1];
double s2 = axis.Length();
if (s2>0)
{
angle = atan2(s2,c2);
axis *= 1/s2;
return;
}
if (c2>=2) // angle is 0
{
axis = vec3(1,0,0);
angle = 0;
return;
}
angle = pi;
int choice = 0; // assume entry[0][0] is the largest
if ((entry[1][1]>entry[0][0]) && (entry[1][1]>entry[2][2])) choice=1;
if ((entry[2][2]>entry[0][0]) && (entry[2][2]>entry[1][1])) choice=2;
if (choice==0)
{
axis.x = 0.5*sqrt(entry[0][0]-entry[1][1]-entry[2][2]+1);
double half_inv = 0.5/axis.x;
axis.y = half_inv*entry[0][1];
axis.z = half_inv*entry[0][2];
return;
}
if (choice==1)
{
axis.y = 0.5*sqrt(entry[1][1]-entry[0][0]-entry[2][2]+1);
double half_inv = 0.5/axis.y;
axis.x = half_inv*entry[0][1];
axis.z = half_inv*entry[1][2];
return;
}
axis.z = 0.5*sqrt(entry[2][2]-entry[0][0]-entry[1][1]+1);
double half_inv = 0.5/axis.z;
axis.x = half_inv*entry[0][2];
axis.y = half_inv*entry[1][2];
}
void rotmatrix::Make_CPAC_Euler_Matrix
(double alpha, double beta, double gamma)
{
double ca=cos(alpha), cb=cos(beta), cg=cos(gamma);
double sa=sin(alpha), sb=sin(beta), sg=sin(gamma);
entry[0][0]= ca*cb*cg-sa*sg; entry[0][1]=-ca*cb*sg-sa*cg; entry[0][2]= ca*sb;
entry[1][0]= sa*cb*cg+ca*sg; entry[1][1]=-sa*cb*sg+ca*cg; entry[1][2]= sa*sb;
entry[2][0]=-sb*cg; entry[2][1]= sb*sg; entry[2][2]= cb;
}
void rotmatrix::Extract_CPAC_Euler_Angles
(double &alpha, double &beta, double &gamma) const
{
double cb = entry[2][2];
double sb = sqrt(entry[0][2]*entry[0][2] + entry[1][2]*entry[1][2]);
beta=atan2(sb,cb);
if (abs(sb)<=1e-6)
{
alpha=0;
if (cb>0)
gamma=atan2(entry[1][0],entry[0][0]);
else
gamma=atan2(entry[0][1],-entry[0][0]);
}
else
{
alpha=atan2(entry[1][2],entry[0][2]);
gamma=atan2(entry[2][1],-entry[2][0]);
}
}
rotmatrix operator* (const rotmatrix &a, const rotmatrix &b)
{
rotmatrix res;
for (int i=0; i<3; ++i)
for (int j=0; j<3; ++j)
res.entry[i][j] = a.entry[i][0] * b.entry[0][j]
+ a.entry[i][1] * b.entry[1][j]
+ a.entry[i][2] * b.entry[2][j];
return res;
}
void TransposeTimes (const rotmatrix &a, const rotmatrix &b, rotmatrix &res)
{
for (int i=0; i<3; ++i)
for (int j=0; j<3; ++j)
res.entry[i][j] = a.entry[0][i] * b.entry[0][j]
+ a.entry[1][i] * b.entry[1][j]
+ a.entry[2][i] * b.entry[2][j];
}
ostream &operator<< (ostream &os, const rotmatrix &mat)
{
for (int i=0;i<3;++i)
os << mat.entry[i][0] << ' '
<< mat.entry[i][1] << ' '
<< mat.entry[i][2] << endl;
return os;
}

158
external/healpix/cxxsupport/rotmatrix.h vendored Normal file
View file

@ -0,0 +1,158 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file rotmatrix.h
* Class for rotation transforms in 3D space
*
* Copyright (C) 2003 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_ROTMATRIX_H
#define PLANCK_ROTMATRIX_H
#include <iostream>
#include "cxxutils.h"
#include "vec3.h"
/*! \defgroup rotmatrixgroup Rotation matrices */
/*! \{ */
/*! Class for rotation transforms in 3D space */
class rotmatrix
{
public:
double entry[3][3];
rotmatrix () {}
/*! Constructs a rotation matrix from its nine entries */
rotmatrix (double a00, double a01, double a02,
double a10, double a11, double a12,
double a20, double a21, double a22)
{
entry[0][0]=a00; entry[0][1]=a01; entry[0][2]=a02;
entry[1][0]=a10; entry[1][1]=a11; entry[1][2]=a12;
entry[2][0]=a20; entry[2][1]=a21; entry[2][2]=a22;
}
/*! Constructs a rotation matrix so that \a a is the first column,
\a b is the second column and \a c is the third column.
\note The vectors \a a, \a b and \a c must form an orthonormal system!
*/
rotmatrix (const vec3 &a, const vec3 &b, const vec3 &c);
/*! Sets the matrix to the identity matrix. */
void SetToIdentity ();
/*! Sets all matrix elements to zero. */
void SetToZero ();
/*! Transposes the matrix. */
void Transpose ();
/*! Extracts a unit-length rotation axis \a axis and a rotation angle
\a angle from the matrix. */
void toAxisAngle (vec3 &axis, double &angle) const;
/*! Constructs a matrix which causes a rotation by \a angle around
\a axis. \a axis must have unit length. */
void Make_Axis_Rotation_Transform (const vec3 &axis, double angle)
{
double sa=sin(angle), ca=cos(angle);
double ica=1-ca;
entry[0][0] = axis.x*axis.x*ica + ca;
entry[1][1] = axis.y*axis.y*ica + ca;
entry[2][2] = axis.z*axis.z*ica + ca;
double t1 = axis.x*axis.y*ica, t2 = axis.z*sa;
entry[1][0] = t1 + t2;
entry[0][1] = t1 - t2;
t1 = axis.x*axis.z*ica; t2 = axis.y*sa;
entry[2][0] = t1 - t2;
entry[0][2] = t1 + t2;
t1 = axis.y*axis.z*ica; t2 = axis.x*sa;
entry[1][2] = t1 - t2;
entry[2][1] = t1 + t2;
}
/*! Creates a rotation matrix \a A, which performs the following operations
on a vector \a v, when \a Av is calculated:
-# rotate \a v around the z-axis by \a gamma,
-# rotate \a v' around the y-axis by \a beta,
-# rotate \a v'' around the z-axis by \a alpha.
\note \a alpha, \a beta and \a gamma are given in radians,
the rotations are right handed.
\note This transformation rotates the \e vectors, not the coordinate
axes! */
void Make_CPAC_Euler_Matrix (double alpha, double beta, double gamma);
/*! Extracts the Euler angles \a alpha, \a beta and \a gamma from the
matrix. For their definition see Make_CPAC_Euler_Matrix().
\note In case of ambiguity \a alpha will be 0. */
void Extract_CPAC_Euler_Angles
(double &alpha, double &beta, double &gamma) const;
/*! Returns the vector \a vec, transformed by the matrix. */
vec3 Transform (const vec3 &vec) const
{
return vec3
(vec.x*entry[0][0] + vec.y*entry[0][1] + vec.z*entry[0][2],
vec.x*entry[1][0] + vec.y*entry[1][1] + vec.z*entry[1][2],
vec.x*entry[2][0] + vec.y*entry[2][1] + vec.z*entry[2][2]);
}
/*! Returns the vector \a vec, transformed by the matrix, in \a vec2. */
void Transform (const vec3 &vec, vec3 &vec2) const
{
vec2.x = vec.x*entry[0][0] + vec.y*entry[0][1] + vec.z*entry[0][2];
vec2.y = vec.x*entry[1][0] + vec.y*entry[1][1] + vec.z*entry[1][2];
vec2.z = vec.x*entry[2][0] + vec.y*entry[2][1] + vec.z*entry[2][2];
}
};
/*! Returns \a a * \a b.
\relates rotmatrix */
rotmatrix operator* (const rotmatrix &a, const rotmatrix &b);
/*! Returns \a a * \a b in \a res.
\relates rotmatrix */
inline void matmult (const rotmatrix &a, const rotmatrix &b, rotmatrix &res)
{
for (int i=0; i<3; ++i)
for (int j=0; j<3; ++j)
res.entry[i][j] = a.entry[i][0] * b.entry[0][j]
+ a.entry[i][1] * b.entry[1][j]
+ a.entry[i][2] * b.entry[2][j];
}
/*! Returns \a a^T * \a b in \a res.
\relates rotmatrix */
void TransposeTimes (const rotmatrix &a, const rotmatrix &b, rotmatrix &res);
/*! Writes \a mat to \a os.
\relates rotmatrix */
std::ostream &operator<< (std::ostream &os, const rotmatrix &mat);
/*! \} */
#endif

92
external/healpix/cxxsupport/safe_cast.h vendored Normal file
View file

@ -0,0 +1,92 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file safe_cast.h
* Numerical cast operator with additional checks that the value is preserved.
*
* Copyright (C) 2009 Max-Planck-Society
* Author: Martin Reinecke
*/
#ifndef PLANCK_SAFE_CAST_H
#define PLANCK_SAFE_CAST_H
#include <limits>
#include "error_handling.h"
template<typename T1, typename T2, bool s1, bool s2> struct safe_cast_helper__
{};
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,true,true>
{
static T1 cast (const T2 &arg)
{
T1 res = T1(arg);
planck_assert(T2(res)==arg, "safe_cast: value changed during cast");
return res;
}
};
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,false,false>
{
static T1 cast (const T2 &arg)
{
T1 res = T1(arg);
planck_assert(T2(res)==arg, "safe_cast: value changed during cast");
return res;
}
};
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,true,false>
{
static T1 cast (const T2 &arg)
{
T1 res = T1(arg);
planck_assert((res>=0) && (T2(res)==arg),
"safe_cast: value changed during cast");
return res;
}
};
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,false,true>
{
static T1 cast (const T2 &arg)
{
T1 res = T1(arg);
planck_assert((arg>=0) && (T2(res)==arg),
"safe_cast: value changed during cast");
return res;
}
};
/*! Tries to cast \a arg from its type to a variable of type \c T1.
If this conversion leads to a change of the actual value (e.g. due to
overflow or truncation), an exception is thrown. */
template<typename T1, typename T2> inline T1 safe_cast(const T2 &arg)
{
return safe_cast_helper__<T1,T2,std::numeric_limits<T1>::is_signed,
std::numeric_limits<T2>::is_signed>::cast(arg);
}
#endif

158
external/healpix/cxxsupport/trafos.cc vendored Normal file
View file

@ -0,0 +1,158 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file trafos.cc
* Celestial coordinate transformations.
*
* Copyright (C) 2005 Max-Planck-Society
* \author Martin Reinecke
*/
#include "trafos.h"
#include "lsconstants.h"
using namespace std;
vec3 Trafo::xcc_dp_precess (const vec3 &iv, double iepoch,
double oepoch)
{
// Z-axis rotation by OBL_LONG:
double Tm = ((oepoch+iepoch)*0.5 - 1900.) *0.01;
double gp_long = degr2rad * ((oepoch-iepoch) * (50.2564+0.0222*Tm) / 3600.);
double obl_long =
degr2rad * (180. - (173. + (57.06+54.77*Tm) / 60.)) + gp_long*0.5;
double dco = cos(obl_long), dso = sin(obl_long);
vec3 ov (iv.x*dco-iv.y*dso, iv.x*dso+iv.y*dco, iv.z);
// X-axis rotation by dE:
double dE = degr2rad * ((oepoch-iepoch) * (0.4711-0.0007*Tm) / 3600.);
double dce = cos(dE), dse = sin(dE);
double temp = ov.y*dce - ov.z*dse;
ov.z = ov.y*dse + ov.z*dce;
ov.y = temp;
// Z-axis rotation by GP_LONG - OBL_LONG:
double dL = gp_long - obl_long;
double dcl = cos(dL), dsl = sin(dL);
temp = ov.x*dcl - ov.y*dsl;
ov.y = ov.x*dsl + ov.y*dcl;
ov.x = temp;
return ov;
}
double Trafo::get_epsilon (double epoch)
{
double T = (epoch - 1900.) * 0.01;
return
degr2rad * (23.452294 - 0.0130125*T - 1.63889e-6*T*T + 5.02778e-7*T*T*T);
}
/*! Routine to convert from ecliptic coordinates to equatorial (celestial)
coordinates at the given epoch. Adapted from the COBLIB routine by Dr.
E. Wright. */
vec3 Trafo::xcc_dp_e_to_q (const vec3 &iv, double epoch)
{
double epsilon=get_epsilon(epoch);
double dc = cos(epsilon), ds = sin(epsilon);
return vec3 (iv.x, dc*iv.y-ds*iv.z, dc*iv.z+ds*iv.y);
}
vec3 Trafo::xcc_dp_q_to_e (const vec3 &iv, double epoch)
{
double epsilon=-get_epsilon(epoch);
double dc = cos(epsilon), ds = sin(epsilon);
return vec3 (iv.x, dc*iv.y-ds*iv.z, dc*iv.z+ds*iv.y);
}
/*! Routine to convert galactic coordinates to ecliptic (celestial)
coordinates at the given epoch. First the conversion to ecliptic
2000 is done, then if necessary the results are precessed. */
vec3 Trafo::xcc_dp_g_to_e (const vec3 &iv, double epoch)
{
static const rotmatrix T (-0.054882486, 0.494116468, -0.867661702,
-0.993821033, -0.110993846, -0.000346354,
-0.096476249, 0.862281440, 0.497154957);
vec3 hv=T.Transform(iv);
if (!approx(epoch,2000.))
hv=xcc_dp_precess(hv,2000.,epoch);
return hv;
}
/*! Routine to convert ecliptic (celestial) coordinates at the given
epoch to galactic coordinates. The ecliptic coordinates are first
precessed to 2000.0, then converted. */
vec3 Trafo::xcc_dp_e_to_g (const vec3 &iv, double epoch)
{
static const rotmatrix T (-0.054882486, -0.993821033, -0.096476249,
0.494116468, -0.110993846, 0.862281440,
-0.867661702, -0.000346354, 0.497154957);
vec3 hv=iv;
if (!approx(epoch,2000.))
hv=xcc_dp_precess(hv,epoch,2000.);
return T.Transform(hv);
}
/*! Function to convert between standard coordinate systems, including
precession. */
vec3 Trafo::xcc_v_convert(const vec3 &iv, double iepoch, double oepoch,
coordsys isys,coordsys osys)
{
vec3 xv;
if (isys == Ecliptic)
xv=iv;
else if (isys == Equatorial)
xv = xcc_dp_q_to_e(iv,iepoch);
else if (isys == Galactic)
xv = xcc_dp_g_to_e(iv,iepoch);
else
planck_fail("Unsupported input coordinate system");
vec3 yv = approx(iepoch,oepoch) ? xv : xcc_dp_precess(xv,iepoch,oepoch);
vec3 ov;
if (osys == Ecliptic)
ov = yv;
else if (osys == Equatorial)
ov = xcc_dp_e_to_q(yv,oepoch);
else if (osys == Galactic)
ov = xcc_dp_e_to_g(yv,oepoch);
else
planck_fail("Unsupported output coordinate system");
return ov;
}
void Trafo::coordsys2matrix (double iepoch, double oepoch,
coordsys isys, coordsys osys, rotmatrix &matrix)
{
vec3 v1p = xcc_v_convert(vec3(1,0,0),iepoch,oepoch,isys,osys),
v2p = xcc_v_convert(vec3(0,1,0),iepoch,oepoch,isys,osys),
v3p = xcc_v_convert(vec3(0,0,1),iepoch,oepoch,isys,osys);
v1p.Normalize(); v2p.Normalize(); v3p.Normalize();
matrix=rotmatrix(v1p,v2p,v3p);
}

103
external/healpix/cxxsupport/trafos.h vendored Normal file
View file

@ -0,0 +1,103 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file trafos.h
* Celestial coordinate transformations.
*
* Copyright (C) 2005 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_TRAFOS_H
#define PLANCK_TRAFOS_H
#include "vec3.h"
#include "pointing.h"
#include "rotmatrix.h"
#include "cxxutils.h"
#include "geom_utils.h"
enum coordsys { Ecliptic, Equatorial, Galactic };
/*! Class for celestial coordinate transformations. */
class Trafo
{
private:
rotmatrix mat;
static vec3 xcc_dp_precess (const vec3 &iv, double iepoch, double oepoch);
static double get_epsilon (double epoch);
static vec3 xcc_dp_e_to_q (const vec3 &iv, double epoch);
static vec3 xcc_dp_q_to_e (const vec3 &iv, double epoch);
static vec3 xcc_dp_g_to_e (const vec3 &iv, double epoch);
static vec3 xcc_dp_e_to_g (const vec3 &iv, double epoch);
static vec3 xcc_v_convert(const vec3 &iv, double iepoch, double oepoch,
coordsys isys,coordsys osys);
static void coordsys2matrix (double iepoch, double oepoch, coordsys isys,
coordsys osys, rotmatrix &matrix);
public:
/*! Creates a \a Trafo for transformation from \a iepoch and \a isys
to \a oepoch and \a osys. */
Trafo (double iepoch, double oepoch, coordsys isys, coordsys osys)
{ coordsys2matrix (iepoch, oepoch, isys, osys, mat); }
/*! Transforms the vector \a vec and returns the result. */
vec3 operator() (const vec3 &vec) const
{ return mat.Transform(vec); }
/*! Transforms the pointing \a ptg and returns the result. */
pointing operator() (const pointing &ptg) const
{ return pointing(operator()(vec3(ptg))); }
/*! Transforms the pointing \a ptg and returns it in \a newptg.
On exit, \a delta_psi holds the change in orientation. */
void rotatefull (const pointing &ptg, pointing &newptg,
double &delta_psi) const
{
const double halfpi_=1.570796326794896619231321691639751442099;
vec3 vec (ptg);
vec3 east (-vec.y,vec.x,0.);
vec3 newvec = operator()(vec);
vec3 neweast = operator()(east);
delta_psi = orientation(newvec,neweast)+halfpi_;
newptg = newvec;
}
/*! Transforms the vector \a vec and returns it in \a newvec.
On exit, \a delta_psi holds the change in orientation. */
void rotatefull (const vec3 &vec, vec3 &newvec, double &delta_psi) const
{
const double halfpi_=1.570796326794896619231321691639751442099;
vec3 east (-vec.y,vec.x,0.);
newvec = operator()(vec);
vec3 neweast = operator()(east);
delta_psi = orientation(newvec,neweast)+halfpi_;
}
/*! Returns the internally used rotation matrix. */
const rotmatrix &Matrix() const
{ return mat; }
};
#endif

149
external/healpix/cxxsupport/vec3.h vendored Normal file
View file

@ -0,0 +1,149 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file vec3.h
* Class representing 3D cartesian vectors
*
* Copyright (C) 2003, 2006 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_VEC3_H
#define PLANCK_VEC3_H
#include <cmath>
#include <iostream>
#include "datatypes.h"
/*! \defgroup vec3group 3D vectors */
/*! \{ */
/*! Class representing a 3D cartesian vector. */
template<typename T>class vec3_t
{
public:
T x, /*!< x-coordinate */
y, /*!< y-coordinate */
z; /*!< z-coordinate */
/*! Default constructor. Does not initialize \a x, \a y, and \a z. */
vec3_t () {}
/*! Creates a vector with the coordinates \a xc, \a yc, and \a zc. */
vec3_t (T xc, T yc, T zc)
: x(xc), y(yc), z(zc) {}
template<typename T2> explicit vec3_t (const vec3_t<T2> &orig)
: x(orig.x), y(orig.y), z(orig.z) {}
/*! Sets the vector components to \a xc, \a yc, and \a zc. */
void Set (T xc, T yc, T zc)
{ x=xc; y=yc; z=zc; }
/*! Creates a unit vector from a z coordinate and an azimuthal angle. */
void set_z_phi (T z_, T phi)
{
using namespace std;
T sintheta = sqrt((T(1)-z_)*(T(1)+z_));
x = sintheta*cos(phi);
y = sintheta*sin(phi);
z = z_;
}
/*! Normalizes the vector to length 1. */
void Normalize ()
{
using namespace std;
T l = T(1)/sqrt (x*x + y*y + z*z);
x*=l; y*=l; z*=l;
}
vec3_t Norm() const
{
vec3_t res(*this);
res.Normalize();
return res;
}
/*! Returns the length of the vector. */
T Length () const
{ return sqrt (x*x + y*y + z*z); }
/*! Returns the squared length of the vector. */
T SquaredLength () const
{ return (x*x + y*y + z*z); }
/*! Returns the vector with the signs of all coordinates flipped. */
const vec3_t operator- () const
{ return vec3_t (-x, -y, -z); }
/*! Flips the signs of all coordinates. */
void Flip ()
{ x=-x; y=-y; z=-z; }
/*! Returns (\a *this + \a vec). */
const vec3_t operator+ (const vec3_t &vec) const
{ return vec3_t (x+vec.x, y+vec.y, z+vec.z); }
/*! Adds \a vec to \a *this. */
vec3_t &operator+= (const vec3_t &vec)
{ x+=vec.x; y+=vec.y; z+=vec.z; return *this; }
/*! Returns (\a *this - \a vec). */
const vec3_t operator- (const vec3_t &vec) const
{ return vec3_t (x-vec.x, y-vec.y, z-vec.z); }
/*! Subtracts \a vec from \a *this. */
vec3_t &operator-= (const vec3_t &vec)
{ x-=vec.x; y-=vec.y; z-=vec.z; return *this; }
/*! Returns the vector scaled by \a fact. */
const vec3_t operator* (T fact) const
{ return vec3_t (x*fact, y*fact, z*fact); }
/*! Returns the vector scaled by \a 1/fact. */
const vec3_t operator/ (T fact) const
{ T xfact = T(1)/fact; return vec3_t (x*xfact, y*xfact, z*xfact); }
/*! Scales the vector by \a fact. */
vec3_t &operator*= (T fact)
{ x*=fact; y*=fact; z*=fact; return *this; }
};
/*! Returns the dot product of \a v1 and \a v2.
\relates vec3_t */
template<typename T> inline T dotprod(const vec3_t<T> &v1, const vec3_t<T> &v2)
{ return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; }
/*! Returns the cross product of \a a and \a b.
\relates vec3_t */
template<typename T> inline vec3_t<T> crossprod
(const vec3_t<T> &a, const vec3_t<T> &b)
{ return vec3_t<T>(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); }
/*! Writes \a v to \a os.
\relates vec3_t */
template<typename T> inline std::ostream &operator<<
(std::ostream &os, const vec3_t<T> &v)
{
os << v.x << ", " << v.y << ", " << v.z << std::endl;
return os;
}
/*! Specialisation of vec3_t for 64-bit floating point components */
typedef vec3_t<float64> vec3;
/*! Specialisation of vec3_t for 32-bit floating point components */
typedef vec3_t<float32> vec3f;
/*! \} */
#endif

583
external/healpix/cxxsupport/wigner.cc vendored Normal file
View file

@ -0,0 +1,583 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file wigner.cc
* Several C++ classes for calculating Wigner matrices
*
* Copyright (C) 2009,2010 Max-Planck-Society
* \author Martin Reinecke and others (see individual classes)
*/
#include "wigner.h"
#include "lsconstants.h"
using namespace std;
void wigner_d_halfpi_risbo_scalar::do_line0 (double *l1, int j)
{
double xj = pq/j;
for (int i=n; i>=1; --i)
l1[i] = xj*sqt[j]*(sqt[j-i]*l1[i] - sqt[i]*l1[i-1]);
l1[0] = pq*l1[0];
}
void wigner_d_halfpi_risbo_scalar::do_line (const double *l1, double *l2,
int j, int k)
{
double xj = pq/j;
double t1 = xj*sqt[j-k];
double t2 = xj*sqt[k];
for (int i=n; i>=1; --i)
l2[i] = t1 * (sqt[j-i]*l2[i] - sqt[i]*l2[i-1])
+t2 * (sqt[j-i]*l1[i] + sqt[i]*l1[i-1]);
l2[0] = sqt[j] * (t2*l1[0]+t1*l2[0]);
}
wigner_d_halfpi_risbo_scalar::wigner_d_halfpi_risbo_scalar(int lmax)
: pq(.5*sqrt(2.)), sqt(2*lmax+1), d(lmax+2,lmax+2), n(-1)
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
const arr2<double> &wigner_d_halfpi_risbo_scalar::recurse ()
{
++n;
if (n==0)
d[0][0] = 1;
else if (n==1)
{
d[0][0] = .5; d[0][1] =-pq;
d[1][0] = pq; d[1][1] = 0.;
}
else
{
//padding
int flip = 1;
for (int i=0; i<n; ++i)
{
d[i][n]=flip*d[i][n-2];
d[n][i]=flip*d[n-2][i];
flip=-flip;
}
d[n][n]=flip*d[n-2][n];
do_line (d[n-1],d[n],2*n-1,n);
for (int k=n; k>=2; --k)
{
do_line (d[k-2],d[k-1],2*n-1,k-1);
do_line (d[k-1],d[k],2*n,k);
}
do_line0 (d[0],2*n-1);
do_line (d[0],d[1],2*n,1);
do_line0 (d[0],2*n);
}
return d;
}
void wigner_d_risbo_scalar::do_line0 (double *l1, int j)
{
double xj = 1./j;
l1[j] = -p*l1[j-1];
for (int i=j-1; i>=1; --i)
l1[i] = xj*sqt[j]*(q*sqt[j-i]*l1[i] - p*sqt[i]*l1[i-1]);
l1[0] = q*l1[0];
}
void wigner_d_risbo_scalar::do_line (const double *l1, double *l2, int j, int k)
{
double xj = 1./j;
double t1 = xj*sqt[j-k]*q, t2 = xj*sqt[j-k]*p;
double t3 = xj*sqt[k]*p, t4 = xj*sqt[k]*q;
l2[j] = sqt[j] * (t4*l1[j-1]-t2*l2[j-1]);
for (int i=j-1; i>=1; --i)
l2[i] = t1*sqt[j-i]*l2[i] - t2*sqt[i]*l2[i-1]
+t3*sqt[j-i]*l1[i] + t4*sqt[i]*l1[i-1];
l2[0] = sqt[j] * (t3*l1[0]+t1*l2[0]);
}
wigner_d_risbo_scalar::wigner_d_risbo_scalar(int lmax, double ang)
: p(sin(ang/2)), q(cos(ang/2)), sqt(2*lmax+1),
d(lmax+1,2*lmax+1), n(-1)
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
const arr2<double> &wigner_d_risbo_scalar::recurse ()
{
++n;
if (n==0)
d[0][0] = 1;
else if (n==1)
{
d[0][0] = q*q; d[0][1] = -p*q*sqt[2]; d[0][2] = p*p;
d[1][0] = -d[0][1]; d[1][1] = q*q-p*p; d[1][2] = d[0][1];
}
else
{
// padding
int sign = (n&1)? -1 : 1;
for (int i=0; i<=2*n-2; ++i)
{
d[n][i] = sign*d[n-2][2*n-2-i];
sign=-sign;
}
do_line (d[n-1],d[n],2*n-1,n);
for (int k=n; k>=2; --k)
{
do_line (d[k-2],d[k-1],2*n-1,k-1);
do_line (d[k-1],d[k],2*n,k);
}
do_line0 (d[0],2*n-1);
do_line (d[0],d[1],2*n,1);
do_line0 (d[0],2*n);
}
return d;
}
wigner_d_halfpi_risbo_openmp::wigner_d_halfpi_risbo_openmp(int lmax)
: pq(.5*sqrt(2.)), sqt(2*lmax+1), d(lmax+2,lmax+2),
dd(lmax+2,lmax+2), n(-1)
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
const arr2<double> &wigner_d_halfpi_risbo_openmp::recurse ()
{
++n;
if (n==0)
d[0][0] = 1;
else if (n==1)
{
d.fast_alloc(3,3);
d[0][0] = .5; d[0][1] =-pq;
d[1][0] = pq; d[1][1] = 0.;
}
else
{
//padding
int flip = 1;
for (int i=0; i<n; ++i)
{
d[i][n]=flip*d[i][n-2];
d[n][i]=flip*d[n-2][i];
flip=-flip;
}
d[n][n]=flip*d[n-2][n];
for (int j=2*n-1; j<=2*n; ++j)
{
dd.fast_alloc(n+2,n+2);
double tmpx1 = pq/j;
dd[0][0] = pq*d[0][0];
for (int i=1;i<=n; ++i)
dd[0][i] = tmpx1*sqt[j]*(sqt[j-i]*d[0][i] - sqt[i]*d[0][i-1]);
#pragma omp parallel
{
int k;
#pragma omp for schedule(static)
for (k=1; k<=n; ++k)
{
double stmp1=sqt[j-k]*tmpx1;
double stmp2=sqt[k]*tmpx1;
double save1 = stmp1*d[k][0], save2 = stmp2*d[k-1][0];
dd[k][0] = sqt[j]*(save1+save2);
for (int i=1; i<=n; ++i)
{
dd[k][i] = sqt[i]*(save2-save1);
save1 = stmp1*d[k][i];
save2 = stmp2*d[k-1][i];
dd[k][i] += sqt[j-i]*(save1+save2);
}
}
}
dd.swap(d);
}
}
return d;
}
wigner_d_risbo_openmp::wigner_d_risbo_openmp(int lmax, double ang)
: p(sin(ang/2)), q(cos(ang/2)), sqt(2*lmax+1),
d(lmax+1,2*lmax+1), dd(lmax+1,2*lmax+1), n(-1)
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
const arr2<double> &wigner_d_risbo_openmp::recurse ()
{
++n;
if (n==0)
d[0][0] = 1;
else if (n==1)
{
d[0][0] = q*q; d[0][1] = -p*q*sqt[2]; d[0][2] = p*p;
d[1][0] = -d[0][1]; d[1][1] = q*q-p*p; d[1][2] = d[0][1];
}
else
{
// padding
int sign = (n&1)? -1 : 1;
for (int i=0; i<=2*n-2; ++i)
{
d[n][i] = sign*d[n-2][2*n-2-i];
sign=-sign;
}
for (int j=2*n-1; j<=2*n; ++j)
{
double xj = 1./j;
dd[0][0] = q*d[0][0];
for (int i=1;i<j; ++i)
dd[0][i] = xj*sqt[j]*(q*sqt[j-i]*d[0][i] - p*sqt[i]*d[0][i-1]);
dd[0][j] = -p*d[0][j-1];
#pragma omp parallel
{
int k;
#pragma omp for schedule(static)
for (k=1; k<=n; ++k)
{
double t1 = xj*sqt[j-k]*q, t2 = xj*sqt[j-k]*p;
double t3 = xj*sqt[k ]*p, t4 = xj*sqt[k ]*q;
dd[k][0] = xj*sqt[j]*(q*sqt[j-k]*d[k][0] + p*sqt[k]*d[k-1][0]);
for (int i=1; i<j; ++i)
dd[k][i] = t1*sqt[j-i]*d[k ][i] - t2*sqt[i]*d[k ][i-1]
+ t3*sqt[j-i]*d[k-1][i] + t4*sqt[i]*d[k-1][i-1];
dd[k][j] = -t2*sqt[j]*d[k][j-1] + t4*sqt[j]*d[k-1][j-1];
}
}
dd.swap(d);
}
}
return d;
}
wignergen::wignergen (int lmax_, const arr<double> &thetas, double epsilon)
: eps(epsilon), lmax(lmax_),
logsum(2*lmax+1), lc05(thetas.size()), ls05(thetas.size()),
flm1(2*lmax+1), flm2(2*lmax+1),
cf(maxscale+1-minscale), costh(thetas.size()), xl(lmax+1),
thetaflip(thetas.size()),
m1(-1234567890), m2(-1234567890), am1(-1234567890), am2(-1234567890),
mlo(-1234567890), mhi(-1234567890),
fx(lmax+2), result(lmax+1)
#ifdef PLANCK_HAVE_SSE2
, result2(lmax+1)
#endif
{
planck_assert(lmax>0,"lmax too small");
logsum[0] = 0.;
for (tsize m=1; m<logsum.size(); ++m)
logsum[m] = logsum[m-1]+log(static_cast<long double>(m));
for (tsize lm=0; lm<flm1.size(); ++lm)
{
flm1[lm] = sqrt(1./(lm+1.));
flm2[lm] = sqrt(lm/(lm+1.));
}
for (tsize i=0; i<cf.size(); ++i)
cf[i] = ldexp(1.,(int(i)+minscale)*large_exponent2);
fsmall = ldexp(1.,-large_exponent2);
fbig = ldexp(1.,large_exponent2);
for (tsize i=0; i<thetas.size(); ++i)
{
double theta=fmodulo(thetas[i],twopi);
if (theta>pi) theta-=twopi;
thetaflip[i]=(theta<0);
theta=abs(theta); // now theta is in (0; pi)
// tiny adjustments to make sure cos and sin (theta/2) are positive
if (theta==0.) theta=1e-16;
if (abs_approx(theta,pi,1e-15)) theta=pi-1e-15;
costh[i]=cos(theta);
lc05[i]=log(cos(0.5L*theta));
ls05[i]=log(sin(0.5L*theta));
}
xl[0]=0;
for (tsize l=1; l<xl.size(); ++l) xl[l]=1./l;
for (tsize l=0; l<fx.size(); ++l)
fx[l][0]=fx[l][1]=fx[l][2]=0.;
}
void wignergen::prepare (int m1_, int m2_)
{
if ((m1_==m1) && (m2_==m2)) return;
int mlo_=abs(m1_), mhi_=abs(m2_);
if (mhi_<mlo_) swap(mhi_,mlo_);
bool ms_similar = ((mhi==mhi_) && (mlo==mlo_));
bool flip_m_sign = ((m1*m2)!=(m1_*m2_));
m1=m1_; m2=m2_;
mlo=am1=abs(m1); mhi=am2=abs(m2);
if (mhi<mlo) swap(mhi,mlo);
if (ms_similar)
{
if (flip_m_sign)
for (int l=mhi; l<lmax; ++l)
fx[l+1][1]=-fx[l+1][1];
}
else
{
for (int l=mhi; l<lmax; ++l)
{
double t = flm1[l+m1]*flm1[l-m1]*flm1[l+m2]*flm1[l-m2];
double lt = 2*l+1;
double l1 = l+1;
fx[l+1][0]=l1*lt*t;
fx[l+1][1]=m1*m2*xl[l]*xl[l+1];
t = flm2[l+m1]*flm2[l-m1]*flm2[l+m2]*flm2[l-m2];
fx[l+1][2]=t*l1*xl[l];
}
}
prefactor = 0.5L*(logsum[2*mhi]-logsum[mhi+mlo]-logsum[mhi-mlo]);
preMinus = false;
if (mhi==am1)
{
cosPow = mhi-m2; sinPow = mhi+m2;
if (m1>=0)
{ swap(cosPow, sinPow); preMinus=((mhi-m2)&1); }
}
else
{
cosPow = mhi+m1; sinPow = mhi-m1;
if (m2<0)
{ swap(cosPow, sinPow); preMinus=((mhi+m1)&1); }
}
}
const arr<double> &wignergen::calc (int nth, int &firstl)
{
int l=mhi;
const dbl3 *fy = &fx[0];
const double cth = costh[nth];
double *res = &result[0];
long double logval = prefactor + lc05[nth]*cosPow + ls05[nth]*sinPow;
logval *= inv_ln2;
int scale = int (logval/large_exponent2)-minscale;
double rec1 = 0.;
double rec2 = double(exp(ln2*(logval-(scale+minscale)*large_exponent2)));
if (preMinus ^ (thetaflip[nth] && ((am1+am2)&1))) rec2 = -rec2;
while(scale<0) // iterate until we reach the realm of IEEE numbers
{
if (++l>lmax) break;
rec1 = (cth - fy[l][1])*fy[l][0]*rec2 - fy[l][2]*rec1;
if (++l>lmax) break;
rec2 = (cth - fy[l][1])*fy[l][0]*rec1 - fy[l][2]*rec2;
while (abs(rec2)>fbig)
{
rec1 *= fsmall;
rec2 *= fsmall;
++scale;
}
}
if (scale<0) { firstl=lmax+1; return result; }
rec1 *= cf[scale];
rec2 *= cf[scale];
for (;l<lmax-1;l+=2) // iterate until we cross the eps threshold
{
if (abs(rec2)>eps) break;
rec1 = (cth - fy[l+1][1])*fy[l+1][0]*rec2 - fy[l+1][2]*rec1;
if (abs(rec1)>eps) { swap(rec1,rec2); ++l; break; }
rec2 = (cth - fy[l+2][1])*fy[l+2][0]*rec1 - fy[l+2][2]*rec2;
}
if ((abs(rec2)<=eps) && (++l<=lmax))
{
rec1 = (cth - fy[l][1])*fy[l][0]*rec2 - fy[l][2]*rec1;
swap (rec1,rec2);
}
firstl = l;
if (l>lmax) return result;
res[l]=rec2;
for (;l<lmax-1;l+=2)
{
res[l+1] = rec1 = (cth - fy[l+1][1])*fy[l+1][0]*rec2 - fy[l+1][2]*rec1;
res[l+2] = rec2 = (cth - fy[l+2][1])*fy[l+2][0]*rec1 - fy[l+2][2]*rec2;
}
while (true)
{
if (++l>lmax) break;
res[l] = rec1 = (cth - fy[l][1])*fy[l][0]*rec2 - fy[l][2]*rec1;
if (++l>lmax) break;
res[l] = rec2 = (cth - fy[l][1])*fy[l][0]*rec1 - fy[l][2]*rec2;
}
return result;
}
#ifdef PLANCK_HAVE_SSE2
#define RENORMALIZE \
do \
{ \
double rec1a, rec1b, rec2a, rec2b, cfa, cfb; \
read_v2df (rec1, &rec1a, &rec1b); read_v2df (rec2, &rec2a, &rec2b); \
read_v2df (corfac, &cfa, &cfb); \
while (abs(rec2a)>fbig) \
{ \
rec1a*=fsmall; rec2a*=fsmall; ++scale1; \
cfa = (scale1<0) ? 0. : cf[scale1]; \
} \
while (abs(rec2b)>fbig) \
{ \
rec1b*=fsmall; rec2b*=fsmall; ++scale2; \
cfb = (scale2<0) ? 0. : cf[scale2]; \
} \
rec1=build_v2df(rec1a,rec1b); rec2=build_v2df(rec2a,rec2b); \
corfac=build_v2df(cfa,cfb); \
} \
while(0)
#define GETPRE(prea,preb,lv) \
prea=_mm_mul_pd(_mm_sub_pd(cth,_mm_set1_pd(fy[lv][1])),_mm_set1_pd(fy[lv][0])); \
preb=_mm_set1_pd(fy[lv][2]);
#define NEXTSTEP(prea,preb,prec,pred,reca,recb,lv) \
{ \
prec = _mm_set1_pd(fy[lv][1]); \
preb = _mm_mul_pd(preb,reca); \
prea = _mm_mul_pd(prea,recb); \
v2df t0 = _mm_set1_pd(fy[lv][0]); \
prec = _mm_sub_pd(cth,prec); \
pred = _mm_set1_pd(fy[lv][2]); \
reca = _mm_sub_pd(prea,preb); \
prec = _mm_mul_pd(prec,t0); \
}
const arr_align<v2df,16> &wignergen::calc (int nth1, int nth2, int &firstl)
{
int l=mhi;
const dbl3 *fy = &fx[0];
const v2df cth = build_v2df(costh[nth1],costh[nth2]);
v2df *res = &result2[0];
long double logval1 = prefactor + lc05[nth1]*cosPow + ls05[nth1]*sinPow,
logval2 = prefactor + lc05[nth2]*cosPow + ls05[nth2]*sinPow;
logval1 *= inv_ln2;
logval2 *= inv_ln2;
int scale1 = int (logval1/large_exponent2)-minscale,
scale2 = int (logval2/large_exponent2)-minscale;
v2df rec1 = _mm_setzero_pd();
double tr1 = double(exp(ln2*(logval1-(scale1+minscale)*large_exponent2))),
tr2 = double(exp(ln2*(logval2-(scale2+minscale)*large_exponent2)));
if (preMinus ^ (thetaflip[nth1] && ((am1+am2)&1))) tr1 = -tr1;
if (preMinus ^ (thetaflip[nth2] && ((am1+am2)&1))) tr2 = -tr2;
v2df rec2 = build_v2df(tr1,tr2);
v2df corfac = build_v2df ( (scale1<0) ? 0. : cf[scale1],
(scale2<0) ? 0. : cf[scale2]);
v2df eps2=build_v2df(eps,eps);
v2df fbig2=build_v2df(fbig,fbig);
v2df pre0,pre1,pre2,pre3;
GETPRE(pre0,pre1,l+1)
if ((scale1<0) && (scale2<0))
{
while (true)
{
if (++l>lmax) break;
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
if (++l>lmax) break;
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+1)
if (v2df_any_gt(rec2,fbig2))
{
RENORMALIZE;
if ((scale1>=0) || (scale2>=0)) break;
}
}
}
if (l<=lmax)
{
GETPRE(pre0,pre1,l+1)
while (true)
{
v2df t1;
res[l]=t1=_mm_mul_pd(rec2,corfac);
if (v2df_any_gt(t1,eps2))
break;
if (++l>lmax) break;
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
res[l]=t1=_mm_mul_pd(rec1,corfac);
if (v2df_any_gt(t1,eps2))
{ swap(rec1,rec2); break; }
if (++l>lmax) break;
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+1)
if (v2df_any_gt(rec2,fbig2))
RENORMALIZE;
}
}
firstl=l;
if (l>lmax) return result2;
GETPRE(pre0,pre1,l+1)
while (true)
{
v2df t1;
res[l]=t1=_mm_mul_pd(rec2,corfac);
if (v2df_all_ge(t1,eps2))
break;
if (++l>lmax) break;
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
res[l]=t1=_mm_mul_pd(rec1,corfac);
if (v2df_all_ge(t1,eps2))
{ swap(rec1,rec2); break; }
if (++l>lmax) break;
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+1)
if (v2df_any_gt(rec2,fbig2))
RENORMALIZE;
}
if (l>lmax) return result2;
rec1 = _mm_mul_pd (rec1,corfac);
rec2 = _mm_mul_pd (rec2,corfac);
GETPRE(pre0,pre1,l+1)
for (;l<lmax-1;l+=2)
{
res[l] = rec2;
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+2)
res[l+1] = rec1;
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+3)
}
res[l] = rec2;
if (++l<=lmax)
{
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
res[l] = rec1;
}
return result2;
}
#endif /* PLANCK_HAVE_SSE2 */

169
external/healpix/cxxsupport/wigner.h vendored Normal file
View file

@ -0,0 +1,169 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file wigner.h
* Several C++ classes for calculating Wigner matrices
*
* Copyright (C) 2009,2010 Max-Planck-Society
* \author Martin Reinecke and others (see individual classes)
*/
#ifndef PLANCK_WIGNER_H
#define PLANCK_WIGNER_H
#include <cmath>
#include "arr.h"
#include "sse_utils.h"
/*! Class for calculation of the Wigner matrix at pi/2, using Risbo recursion
in a way that cannot easily be parallelised, but is fairly efficient on
scalar machines. */
class wigner_d_halfpi_risbo_scalar
{
private:
double pq;
arr<double> sqt;
arr2<double> d;
int n;
void do_line0 (double *l1, int j);
void do_line (const double *l1, double *l2, int j, int k);
public:
wigner_d_halfpi_risbo_scalar(int lmax);
const arr2<double> &recurse ();
};
/*! Class for calculation of the Wigner matrix at arbitrary angles, using Risbo
recursion in a way that cannot easily be parallelised, but is fairly
efficient on scalar machines. */
class wigner_d_risbo_scalar
{
private:
double p,q;
arr<double> sqt;
arr2<double> d;
int n;
void do_line0 (double *l1, int j);
void do_line (const double *l1, double *l2, int j, int k);
public:
wigner_d_risbo_scalar(int lmax, double ang);
const arr2<double> &recurse ();
};
/*! Class for calculation of the Wigner matrix at pi/2, using Risbo recursion
in a way that can be OpenMP-parallelised. This approach uses more memory
and is slightly slower than wigner_d_halfpi_risbo_scalar. */
class wigner_d_halfpi_risbo_openmp
{
private:
double pq;
arr<double> sqt;
arr2<double> d,dd;
int n;
public:
wigner_d_halfpi_risbo_openmp(int lmax);
const arr2<double> &recurse ();
};
/*! Class for calculation of the Wigner matrix at arbitrary angles, using Risbo
recursion in a way that can be OpenMP-parallelised. This approach uses more
memory and is slightly slower than wigner_d_risbo_scalar. */
class wigner_d_risbo_openmp
{
private:
double p,q;
arr<double> sqt;
arr2<double> d, dd;
int n;
public:
wigner_d_risbo_openmp(int lmax, double ang);
const arr2<double> &recurse ();
};
/*! Class for calculation of the Wigner matrix elements by l-recursion.
For details, see Prezeau & Reinecke 2010, http://arxiv.org/pdf/1002.1050 */
class wignergen
{
private:
typedef double dbl3[3];
// members set in the constructor and kept fixed afterwards
double fsmall, fbig, eps;
int lmax;
arr<long double> logsum, lc05, ls05;
arr<double> flm1, flm2, cf, costh, xl;
arr<bool> thetaflip;
// members depending on m and m'
int m1, m2, am1, am2, mlo, mhi, cosPow, sinPow;
long double prefactor;
arr<dbl3> fx;
bool preMinus;
// members depending on theta
arr<double> result;
#ifdef PLANCK_HAVE_SSE2
arr_align<v2df,16> result2;
#endif
enum { large_exponent2=90, minscale=-4, maxscale=14 };
public:
/*! Constructs an object that can compute Wigner matrix elements up
to a maximum \a l value of \a lmax_, at the colatitudes provided
in \a thetas. The generator will be allowed to regard values with
absolute magnitudes smaller than \a epsilon as zero; a typical value
is 1e-30. */
wignergen (int lmax_, const arr<double> &thetas, double epsilon);
/*! Prepares the object to produce Wigner matrix elements with \a m=m1_
and \a m'=m2_ in subsequent calls to calc(). This operation is not cheap
so it is recommended to use calc() for many different colatitudes after
every call to prepare(), if possible. */
void prepare (int m1_, int m2_);
/*! Computes the Wigner matrix elements for the values of \a m and \a m'
set by the preceding call to prepare(), for all \a l up to \a lmax
(set in the constructor), and for the \a nth colatitude passed to the
constructor. On return, \a firstl contains the index of the first
matrix element larger than \a epsilon; all values with smaller indices
in the result array are undefined. */
const arr<double> &calc (int nth, int &firstl);
#ifdef PLANCK_HAVE_SSE2
const arr_align<v2df,16> &calc (int nth1, int nth2, int &firstl);
#endif
};
#endif

208
external/healpix/cxxsupport/xcomplex.h vendored Normal file
View file

@ -0,0 +1,208 @@
/*
* This file is part of libcxxsupport.
*
* libcxxsupport 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.
*
* libcxxsupport is distributed in the hope that 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 libcxxsupport; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
* (DLR).
*/
/*! \file xcomplex.h
* Class for representing complex numbers, strongly inspired by C++'s
* std::complex
*
* Copyright (C) 2003-2010 Max-Planck-Society
* \author Martin Reinecke
*/
#ifndef PLANCK_XCOMPLEX_H
#define PLANCK_XCOMPLEX_H
#include <iostream>
#include <complex>
/*! \defgroup complexgroup Complex number support */
/*! \{ */
/*! A class for representing complex numbers.
This template is intended as an (under-encapsulated) replacement for
the (over-encapsulated) std::complex<>. The goal is to include the
whole functionality of std::complex<>, with some additional methods
that allow higher performance.
The (known and intentional) differences between xcomplex<> and
std::complex<> are:
- the default constructor of xcomplex<> does nothing, in contrast to
std::complex<>, which initialises its members to zero.
- xcomplex<> implements the methods real() and imag() according
to defect report DR387
*/
template<typename T> class xcomplex
{
public:
T re, /*!< real part */
im; /*!< imaginary part */
/*! Default constructor. \a re and \a im are not initialised. */
xcomplex () {}
/*! Creates the complex number (\a re_, \a im_). */
xcomplex (const T &re_, const T &im_)
: re(re_), im(im_) {}
/*! Creates the complex number (\a re_, 0). */
xcomplex (const T &re_)
: re(re_), im(0) {}
/*! Creates an xcomplex from a std::complex of identical precision. */
xcomplex (const std::complex<T> &orig)
: re(orig.real()), im(orig.imag()) {}
/*! Creates a complex number as a copy of \a orig. */
template<typename U> explicit xcomplex (const xcomplex<U> &orig)
: re(T(orig.re)), im(T(orig.im)) {}
/*! Conversion operator to std::complex<T> */
operator std::complex<T> () const
{ return std::complex<T>(re,im); }
/*! Returns the real part as lvalue. */
T &real() { return re; }
/*! Returns the real part. */
const T &real() const { return re; }
/*! Returns the imaginary part as lvalue. */
T &imag() { return im; }
/*! Returns the imaginary part. */
const T &imag() const { return im; }
/*! Sets the number to (\a re_, \a im_). */
void Set (const T &re_, const T &im_)
{ re = re_; im = im_; }
/*! Sets the number to \a orig. */
xcomplex &operator= (const xcomplex &orig)
{ re=orig.re; im=orig.im; return *this; }
/*! Sets the number to \a orig. */
xcomplex &operator= (const std::complex<T> &orig)
{ re=orig.real(); im=orig.imag(); return *this; }
/*! Sets the number to (\a orig, 0). */
xcomplex &operator= (const T &orig)
{ re=orig; im=0; return *this; }
/*! Adds \a b to \a *this. */
xcomplex &operator+= (const xcomplex &b)
{ re+=b.re; im+=b.im; return *this; }
/*! Subtracts \a b from \a *this. */
xcomplex &operator-= (const xcomplex &b)
{ re-=b.re; im-=b.im; return *this; }
/*! Multiplies \a *this by \a b. */
xcomplex &operator*= (const xcomplex &b)
{
T tmp=re;
re=tmp*b.re-im*b.im; im=tmp*b.im+im*b.re;
return *this;
}
/*! Divides \a *this by \a b. */
xcomplex &operator/= (const xcomplex &b)
{
std::complex<T> tmp=*this;
std::complex<T> tmp2=b;
tmp /= tmp2;
*this=tmp;
return *this;
}
/*! Multiplies \a *this by \a fact. */
xcomplex &operator*= (const T &fact)
{ re*=fact; im*=fact; return *this; }
/*! Divides \a *this by \a div. */
xcomplex &operator/= (const T &div)
{ re/=div; im/=div; return *this; }
/*! Returns \a *this * \a fact. */
xcomplex operator* (const T &fact) const
{ return xcomplex (re*fact,im*fact); }
/*! Returns \a *this * \a b. */
xcomplex operator* (const xcomplex &b) const
{ return xcomplex (re*b.re-im*b.im, re*b.im+im*b.re); }
/*! Returns \a *this / \a b. */
xcomplex operator/ (const xcomplex &b) const
{ return xcomplex(std::complex<T>(*this)/std::complex<T>(b)); }
/*! Returns \a *this / \a div. */
xcomplex operator/ (const T &div) const
{ return xcomplex (re/div,im/div); }
/*! Returns \a *this + \a b. */
xcomplex operator+ (const xcomplex &b) const
{ return xcomplex (re+b.re, im+b.im); }
/*! Returns \a *this - \a b. */
xcomplex operator- (const xcomplex &b) const
{ return xcomplex (re-b.re, im-b.im); }
/*! Returns \a -(*this) */
xcomplex operator- () const
{ return xcomplex (-re,-im); }
/*! Flips the signs of both components. */
void Negate()
{ re=-re; im=-im; }
/*! Flips the signs of the imaginary component. */
void Conjugate()
{ im=-im; }
/*! Multiplies the number by exp(i*\a angle) */
void Rotate(T angle)
{
T ca=cos(angle), sa=sin(angle);
T tmp=re;
re=tmp*ca-im*sa; im=tmp*sa+im*ca;
}
/*! Returns the complex conjugate of \a *this. */
xcomplex conj() const
{ return xcomplex (re,-im); }
/*! Returns the norm of \a *this. */
T norm() const
{ return re*re + im*im; }
};
/*! Returns the complex conjugate of \a num.
\relates xcomplex */
template <typename T> inline xcomplex<T> conj (const xcomplex<T> &num)
{ return xcomplex<T> (num.re, -num.im); }
/*! Returns the norm of \a num.
\relates xcomplex */
template <typename T> inline T norm (const xcomplex<T> &num)
{ return num.re*num.re + num.im*num.im; }
/*! Returns the absolute value of \a num.
\relates xcomplex */
template <typename T> inline T abs (const xcomplex<T> &num)
{
using namespace std;
return abs(complex<T>(num));
}
/*! Returns \a f1*f2.
\relates xcomplex */
template <typename T> inline xcomplex<T> operator*
(const T &f1, const xcomplex<T> &f2)
{ return xcomplex<T> (f1*f2.re, f1*f2.im); }
/*! Returns \a f1/f2.
\relates xcomplex */
template <typename T> inline xcomplex<T> operator/
(const T &f1, const xcomplex<T> &f2)
{ return xcomplex<T>(f1)/f2; }
/*! Writes \a val to \a os.
\relates xcomplex */
template<typename T>
inline std::ostream &operator<< (std::ostream &os, const xcomplex<T> &val)
{ os << "(" << val.re << "," << val.im << ")"; return os; }
/*! \} */
#endif

272
external/healpix/docsrc/Healpix_cxx.dox vendored Normal file
View file

@ -0,0 +1,272 @@
# Doxyfile 1.7.0
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Healpix C++"
PROJECT_NUMBER = 0.1
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = YES
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../Healpix_cxx
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.cc \
*.dox
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH = ../Healpix_cxx/
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = htmldoc
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER = footer.html
HTML_STYLESHEET =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
SEARCHENGINE = NO
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = YES
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES = libfftpack.tag=../libfftpack \
cxxsupport.tag=../cxxsupport
GENERATE_TAGFILE = Healpix_cxx.tag
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = FreeSans
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = NO
INCLUDED_BY_GRAPH = NO
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

271
external/healpix/docsrc/c_utils.dox vendored Normal file
View file

@ -0,0 +1,271 @@
# Doxyfile 1.7.0
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "LevelS C support library"
PROJECT_NUMBER = 0.1
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = NO
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = YES
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../c_utils
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.c \
*.dox
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = htmldoc
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER = footer.html
HTML_STYLESHEET =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
SEARCHENGINE = NO
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = YES
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE = c_utils.tag
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = FreeSans
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = NO
INCLUDED_BY_GRAPH = NO
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = NO
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

271
external/healpix/docsrc/cxxsupport.dox vendored Normal file
View file

@ -0,0 +1,271 @@
# Doxyfile 1.7.0
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "LevelS C++ support library"
PROJECT_NUMBER = 0.1
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = NO
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = YES
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../cxxsupport
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.cc \
*.dox
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = htmldoc
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER = footer.html
HTML_STYLESHEET =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
SEARCHENGINE = NO
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = YES
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES = c_utils.tag=../c_utils libfftpack.tag=../libfftpack
GENERATE_TAGFILE = cxxsupport.tag
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = FreeSans
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = NO
INCLUDED_BY_GRAPH = NO
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = NO
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

5
external/healpix/docsrc/footer.html vendored Normal file
View file

@ -0,0 +1,5 @@
<hr><address style="align: right;"><small>
Generated on $datetime for $projectname
</a> </small></address>
</body>
</html>

5
external/healpix/docsrc/header.html vendored Normal file
View file

@ -0,0 +1,5 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>$title</title>
<link href="sheet.css" rel="stylesheet" type="text/css">
</head><body>

22
external/healpix/docsrc/index_code.html vendored Normal file
View file

@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>HEALPix C++ source code documentation</title>
</head><body>
<H1>HEALPix C++ source code documentation</H1>
<H2>C interfaces</H2>
<ul>
<li><a href="c_utils/index.html">LevelS C support library</a>
<li><a href="libfftpack/index.html">LevelS FFT interface</a>
<li><a href="libpsht/index.html">Library for spherical harmonic transforms</a>
</ul>
<H2>C++ interfaces</H2>
<ul>
<li><a href="cxxsupport/index.html">LevelS C++ support library</a>
<li><a href="Healpix_cxx/index.html">Healpix C++ documentation</a>
</ul>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more