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

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;
}