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