00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef HEALPIX_BASE_H
00033 #define HEALPIX_BASE_H
00034
00035 #include <vector>
00036 #include "cxxutils.h"
00037 #include "lsconstants.h"
00038 #include "pointing.h"
00039 template<typename T, unsigned int sz> class fix_arr;
00040
00041
00042 typedef enum { RING,
00043 NEST
00044 } Healpix_Ordering_Scheme;
00045
00046 class nside_dummy {};
00047 extern const nside_dummy SET_NSIDE;
00048
00049
00050 class Healpix_Base
00051 {
00052 protected:
00053 enum { order_max=13 };
00054
00055 class Tablefiller
00056 {
00057 public:
00058 Tablefiller();
00059 };
00060 static Tablefiller Filler;
00061 friend class Tablefiller;
00062
00063 static short ctab[0x100], utab[0x100];
00064
00065 static const int jrll[];
00066 static const int jpll[];
00067
00068
00069 int order_;
00070
00071 int nside_;
00072 int npface_, ncap_, npix_;
00073 double fact1_, fact2_;
00074
00075 Healpix_Ordering_Scheme scheme_;
00076
00077 inline int ring_above (double z) const;
00078 void in_ring (int iz, double phi0, double dphi,
00079 std::vector<int> &listir) const;
00080
00081 int xyf2nest(int ix, int iy, int face_num) const;
00082 void nest2xyf(int pix, int &ix, int &iy, int &face_num) const;
00083 int xyf2ring(int ix, int iy, int face_num) const;
00084 void ring2xyf(int pix, int &ix, int &iy, int &face_num) const;
00085
00086 typedef int (Healpix_Base::*swapfunc)(int pix) const;
00087 typedef void (Healpix_Base::*pix2xyf)
00088 (int pix, int &x, int &y, int &f) const;
00089 typedef int (Healpix_Base::*xyf2pix) (int x, int y, int f) const;
00090
00091 public:
00092
00093
00094
00095 static int nside2order (int nside)
00096 {
00097 planck_assert (nside>0, "invalid value for Nside");
00098 if ((nside)&(nside-1)) return -1;
00099 return ilog2(nside);
00100 }
00101
00102
00103 static int npix2nside (int npix);
00104
00105 Healpix_Base ()
00106 : order_(-1), nside_(0), npface_(0), ncap_(0), npix_(0),
00107 fact1_(0), fact2_(0), scheme_(RING) {}
00108
00109
00110 Healpix_Base (int order, Healpix_Ordering_Scheme scheme)
00111 { Set (order, scheme); }
00112
00113
00114
00115 Healpix_Base (int nside, Healpix_Ordering_Scheme scheme, const nside_dummy)
00116 { SetNside (nside, scheme); }
00117
00118
00119 void Set (int order, Healpix_Ordering_Scheme scheme)
00120 {
00121 planck_assert ((order>=0)&&(order<=order_max), "bad order");
00122 order_ = order;
00123 nside_ = 1<<order;
00124 npface_ = nside_<<order_;
00125 ncap_ = (npface_-nside_)<<1;
00126 npix_ = 12*npface_;
00127 fact2_ = 4./npix_;
00128 fact1_ = (nside_<<1)*fact2_;
00129 scheme_ = scheme;
00130 }
00131
00132 void SetNside (int nside, Healpix_Ordering_Scheme scheme)
00133 {
00134 order_ = nside2order(nside);
00135 planck_assert ((scheme!=NEST) || (order_>=0),
00136 "SetNside: nside must be power of 2 for nested maps");
00137 nside_ = nside;
00138 npface_ = nside_*nside_;
00139 ncap_ = (npface_-nside_)<<1;
00140 npix_ = 12*npface_;
00141 fact2_ = 4./npix_;
00142 fact1_ = (nside_<<1)*fact2_;
00143 scheme_ = scheme;
00144 }
00145
00146
00147
00148 double ring2z (int ring) const;
00149
00150 int pix2ring (int pix) const;
00151
00152
00153 int nest2ring (int pix) const;
00154
00155 int ring2nest (int pix) const;
00156
00157 int nest2peano (int pix) const;
00158
00159 int peano2nest (int pix) const;
00160
00161 int ang2pix_z_phi (double z, double phi) const;
00162
00163
00164
00165 int ang2pix (const pointing &ang) const
00166 { return ang2pix_z_phi (cos(ang.theta), ang.phi); }
00167
00168
00169 int vec2pix (const vec3 &vec) const
00170 { return ang2pix_z_phi (vec.z/vec.Length(), safe_atan2(vec.y,vec.x)); }
00171
00172 void pix2ang_z_phi (int pix, double &z, double &phi) const;
00173
00174
00175
00176 pointing pix2ang (int pix) const
00177 {
00178 double z, phi;
00179 pix2ang_z_phi (pix,z,phi);
00180 return pointing(acos(z),phi);
00181 }
00182
00183 vec3 pix2vec (int pix) const
00184 {
00185 double z, phi;
00186 pix2ang_z_phi (pix,z,phi);
00187 vec3 res;
00188 res.set_z_phi (z, phi);
00189 return res;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199 void query_disc (const pointing &dir, double radius,
00200 std::vector<int> &listpix) const;
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 void query_disc_inclusive (const pointing &dir, double radius,
00211 std::vector<int> &listpix) const
00212 { query_disc (dir,radius+1.362*pi/(4*nside_),listpix); }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 void get_ring_info (int ring, int &startpix, int &ringpix,
00223 double &costheta, double &sintheta, bool &shifted) const;
00224
00225
00226
00227
00228
00229
00230
00231 void get_ring_info2 (int ring, int &startpix, int &ringpix,
00232 double &theta, bool &shifted) const;
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 void neighbors (int pix, fix_arr<int,8> &result) const;
00243
00244
00245
00246
00247
00248 void get_interpol (const pointing &ptg, fix_arr<int,4> &pix,
00249 fix_arr<double,4> &wgt) const;
00250
00251
00252 int Order() const { return order_; }
00253
00254 int Nside() const { return nside_; }
00255
00256 int Npix() const { return npix_; }
00257
00258 Healpix_Ordering_Scheme Scheme() const { return scheme_; }
00259
00260
00261
00262 bool conformable (const Healpix_Base &other) const
00263 { return ((nside_==other.nside_) && (scheme_==other.scheme_)); }
00264
00265
00266 void swap (Healpix_Base &other)
00267 {
00268 std::swap(order_,other.order_);
00269 std::swap(nside_,other.nside_);
00270 std::swap(npface_,other.npface_);
00271 std::swap(ncap_,other.ncap_);
00272 std::swap(npix_,other.npix_);
00273 std::swap(fact1_,other.fact1_);
00274 std::swap(fact2_,other.fact2_);
00275 std::swap(scheme_,other.scheme_);
00276 }
00277
00278
00279
00280 double max_pixrad() const;
00281 };
00282
00283 #endif