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_MAP_H
00033 #define HEALPIX_MAP_H
00034
00035 #include "arr.h"
00036 #include "healpix_base.h"
00037
00038
00039 template<typename T> class Healpix_Map: public Healpix_Base
00040 {
00041 private:
00042 arr<T> map;
00043
00044 public:
00045
00046 Healpix_Map () {}
00047
00048
00049 Healpix_Map (int order, Healpix_Ordering_Scheme scheme)
00050 : Healpix_Base (order, scheme), map(npix_) {}
00051
00052
00053 Healpix_Map (int nside, Healpix_Ordering_Scheme scheme, const nside_dummy)
00054 : Healpix_Base (nside, scheme, SET_NSIDE), map(npix_) {}
00055
00056
00057
00058 Healpix_Map (const arr<T> &data, Healpix_Ordering_Scheme scheme)
00059 : Healpix_Base (npix2nside(data.size()), scheme, SET_NSIDE), map(data) {}
00060
00061
00062
00063
00064 void Set (arr<T> &data, Healpix_Ordering_Scheme scheme)
00065 {
00066 Healpix_Base::SetNside(npix2nside (data.size()), scheme);
00067 map.transfer(data);
00068 }
00069
00070
00071
00072 void Set (int order, Healpix_Ordering_Scheme scheme)
00073 {
00074 Healpix_Base::Set(order, scheme);
00075 map.alloc(npix_);
00076 }
00077
00078
00079 void SetNside (int nside, Healpix_Ordering_Scheme scheme)
00080 {
00081 Healpix_Base::SetNside(nside, scheme);
00082 map.alloc(npix_);
00083 }
00084
00085
00086 void fill (const T &val)
00087 { map.fill(val); }
00088
00089
00090
00091
00092 void Import_nograde (const Healpix_Map<T> &orig)
00093 {
00094 planck_assert (nside_==orig.nside_,
00095 "Import_nograde: maps have different nside");
00096 if (orig.scheme_ == scheme_)
00097 for (int m=0; m<npix_; ++m) map[m] = orig.map[m];
00098 else
00099 {
00100 swapfunc swapper = (scheme_ == NEST) ?
00101 &Healpix_Base::ring2nest : &Healpix_Base::nest2ring;
00102 #pragma omp parallel
00103 {
00104 int m;
00105 #pragma omp for schedule (dynamic,5000)
00106 for (m=0; m<npix_; ++m) map[(this->*swapper)(m)] = orig.map[m];
00107 }
00108 }
00109 }
00110
00111
00112
00113
00114 void Import_upgrade (const Healpix_Map<T> &orig)
00115 {
00116 planck_assert(nside_>orig.nside_,"Import_upgrade: this is no upgrade");
00117 int fact = nside_/orig.nside_;
00118 planck_assert (nside_==orig.nside_*fact,
00119 "the larger Nside must be a multiple of the smaller one");
00120 pix2xyf to_xyf = (orig.scheme_==RING) ?
00121 &Healpix_Map::ring2xyf : &Healpix_Map::nest2xyf;
00122 xyf2pix from_xyf = (scheme_==RING) ?
00123 &Healpix_Map::xyf2ring : &Healpix_Map::xyf2nest;
00124
00125 #pragma omp parallel
00126 {
00127 int m;
00128 #pragma omp for schedule (dynamic,5000)
00129 for (m=0; m<orig.npix_; ++m)
00130 {
00131 int x,y,f;
00132 (orig.*to_xyf)(m,x,y,f);
00133 for (int j=fact*y; j<fact*(y+1); ++j)
00134 for (int i=fact*x; i<fact*(x+1); ++i)
00135 {
00136 int mypix = (this->*from_xyf)(i,j,f);
00137 map[mypix] = orig.map[m];
00138 }
00139 }
00140 }
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 void Import_degrade (const Healpix_Map<T> &orig, bool pessimistic=false);
00152
00153
00154
00155
00156
00157
00158
00159
00160 void Import (const Healpix_Map<T> &orig, bool pessimistic=false)
00161 {
00162 if (orig.nside_ == nside_)
00163 Import_nograde(orig);
00164 else if (orig.nside_ < nside_)
00165 Import_upgrade(orig);
00166 else
00167 Import_degrade(orig,pessimistic);
00168 }
00169
00170
00171 const T &operator[] (int pix) const { return map[pix]; }
00172
00173 T &operator[] (int pix) { return map[pix]; }
00174
00175
00176
00177 void swap_scheme()
00178 {
00179 static const int clen[] = { 0,7,5,4,12,10,13,18,14,19,18,17,27,21 };
00180 static const int cycle[][30] = {
00181 { },
00182 { 0,1,8,12,16,21,40 },
00183 { 0,1,2,40,114 },
00184 { 0,4,160,263 },
00185 { 0,4,30,49,51,87,526,1027,1105,1387,1807,2637 },
00186 { 0,8,10,18,39,74,146,307,452,4737 },
00187 { 0,1,2,7,9,17,80,410,1526,1921,32859,33566,38931 },
00188 { 0,5,6,10,12,24,27,95,372,494,924,1409,3492,4248,9137,66043,103369,
00189 156899 },
00190 { 0,1,2,3,4,45,125,351,697,24337,102940,266194,341855,419857 },
00191 { 0,1,2,3,9,16,1705,2082,2126,8177,12753,15410,52642,80493,83235,
00192 88387,99444,1675361,2495125 },
00193 { 0,2,6,8,9,11,20,50,93,152,183,2137,13671,44794,486954,741908,
00194 4803258,5692573 },
00195 { 0,1,5,6,44,53,470,2847,3433,4906,13654,14710,400447,1797382,
00196 2744492,18775974,23541521 },
00197 { 0,4,9,10,16,33,83,117,318,451,5759,10015,128975,171834,211256,
00198 347608,1278690,2154097,2590798,3427694,5581717,21012301,27023976,
00199 72522811,95032729,139166747,171822389 },
00200 { 0,5,10,267,344,363,2968,3159,9083,18437,76602,147614,1246902,
00201 1593138,2035574,6529391,9511830,11340287,29565945,281666026,
00202 677946848 } };
00203
00204 swapfunc swapper = (scheme_ == NEST) ?
00205 &Healpix_Base::ring2nest : &Healpix_Base::nest2ring;
00206
00207 planck_assert (order_>=0, "swap_scheme(): need hierarchical map");
00208
00209 for (int m=0; m<clen[order_]; ++m)
00210 {
00211 int istart = cycle[order_][m];
00212
00213 T pixbuf = map[istart];
00214 int iold = istart, inew = (this->*swapper)(istart);
00215 while (inew != istart)
00216 {
00217 map[iold] = map[inew];
00218 iold = inew;
00219 inew = (this->*swapper)(inew);
00220 }
00221 map[iold] = pixbuf;
00222 }
00223 scheme_ = (scheme_==RING) ? NEST : RING;
00224 }
00225
00226
00227 T interpolation (const fix_arr<int,4> &pix,
00228 const fix_arr<double,4> &wgt) const
00229 {
00230 return map[pix[0]]*wgt[0] + map[pix[1]]*wgt[1]
00231 + map[pix[2]]*wgt[2] + map[pix[3]]*wgt[3];
00232 }
00233
00234 T interpolated_value (const pointing &ptg) const
00235 {
00236 fix_arr<int,4> pix;
00237 fix_arr<double,4> wgt;
00238 get_interpol (ptg, pix, wgt);
00239 return interpolation (pix, wgt);
00240 }
00241
00242 T interpolated_value2 (const pointing &ptg) const
00243 {
00244 fix_arr<int,4> pix;
00245 fix_arr<double,4> wgt;
00246 get_interpol2 (ptg, pix, wgt);
00247 return interpolation (pix, wgt);
00248 }
00249
00250
00251 const arr<T> &Map() const { return map; }
00252
00253
00254
00255
00256
00257 void minmax (T &Min, T &Max) const;
00258
00259
00260 void swap (Healpix_Map &other)
00261 {
00262 Healpix_Base::swap(other);
00263 map.swap(other.map);
00264 }
00265
00266
00267 double average() const
00268 {
00269 double avg=0;
00270 int pix=0;
00271 for (int m=0; m<npix_; ++m)
00272 if (!approx(map[m],Healpix_undef))
00273 { ++pix; avg+=map[m]; }
00274 return avg/pix;
00275 }
00276
00277
00278 void add (T val)
00279 {
00280 for (int m=0; m<npix_; ++m)
00281 if (!approx(map[m],Healpix_undef))
00282 { map[m]+=val; }
00283 }
00284 };
00285
00286 #endif