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 #include "alm_healpix_tools.h"
00033 #include "alm_map_tools.h"
00034 #include "alm.h"
00035 #include "healpix_map.h"
00036 #include "xcomplex.h"
00037
00038 using namespace std;
00039
00040 namespace {
00041
00042 void healpix2ringpairs (const Healpix_Base &base,
00043 const arr<double> &weight, vector<ringpair> &pair)
00044 {
00045 pair.clear();
00046 int startpix, ringpix;
00047 double theta, wgt, phi0;
00048 bool shifted;
00049 int nside = base.Nside();
00050 for (int m=0; m<2*nside-1; ++m)
00051 {
00052 base.get_ring_info2 (m+1, startpix, ringpix, theta, shifted);
00053 wgt = weight[m]*fourpi/base.Npix();
00054 phi0 = shifted ? pi/ringpix : 0;
00055 pair.push_back (ringpair(
00056 ringinfo(theta, phi0, wgt, ringpix, startpix),
00057 ringinfo(pi-theta, phi0, wgt, ringpix, base.Npix()-startpix-ringpix)));
00058 }
00059 base.get_ring_info2 (2*nside, startpix, ringpix, theta, shifted);
00060 wgt = weight[2*nside-1]*fourpi/base.Npix();
00061 phi0 = shifted ? pi/ringpix : 0;
00062 pair.push_back (ringpair(ringinfo(theta, phi0, wgt, ringpix, startpix)));
00063 }
00064
00065 void healpix2ringpairs (const Healpix_Base &base, vector<ringpair> &pair)
00066 {
00067 arr<double> wgt(2*base.Nside());
00068 wgt.fill(1);
00069 healpix2ringpairs(base,wgt,pair);
00070 }
00071
00072 }
00073
00074
00075 template<typename T> void map2alm (const Healpix_Map<T> &map,
00076 Alm<xcomplex<T> > &alm, const arr<double> &weight, bool add_alm)
00077 {
00078 planck_assert (map.Scheme()==RING, "map2alm: map must be in RING scheme");
00079 planck_assert (weight.size()>=2*map.Nside(),
00080 "map2alm: weight array has too few entries");
00081
00082 vector<ringpair> pair;
00083 healpix2ringpairs(map,weight,pair);
00084 map2alm(pair,&map[0],alm,add_alm);
00085 }
00086
00087 template void map2alm (const Healpix_Map<float> &map,
00088 Alm<xcomplex<float> > &alm, const arr<double> &weight,
00089 bool add_alm);
00090 template void map2alm (const Healpix_Map<double> &map,
00091 Alm<xcomplex<double> > &alm, const arr<double> &weight,
00092 bool add_alm);
00093
00094 template<typename T> void map2alm_iter (const Healpix_Map<T> &map,
00095 Alm<xcomplex<T> > &alm, int num_iter, const arr<double> &weight)
00096 {
00097 map2alm(map,alm,weight);
00098 for (int iter=1; iter<=num_iter; ++iter)
00099 {
00100 Healpix_Map<T> map2(map.Nside(),map.Scheme(),SET_NSIDE);
00101 alm2map(alm,map2);
00102 for (int m=0; m<map.Npix(); ++m)
00103 map2[m] = map[m]-map2[m];
00104 map2alm(map2,alm,weight,true);
00105 }
00106 }
00107
00108 template void map2alm_iter (const Healpix_Map<float> &map,
00109 Alm<xcomplex<float> > &alm, int num_iter,
00110 const arr<double> &weight);
00111 template void map2alm_iter (const Healpix_Map<double> &map,
00112 Alm<xcomplex<double> > &alm, int num_iter,
00113 const arr<double> &weight);
00114
00115 template<typename T> void map2alm_iter2 (const Healpix_Map<T> &map,
00116 Alm<xcomplex<T> > &alm, double err_abs, double err_rel)
00117 {
00118 double x_err_abs=1./err_abs, x_err_rel=1./err_rel;
00119 arr<double> wgt(2*map.Nside());
00120 wgt.fill(1);
00121 Healpix_Map<T> map2(map);
00122 alm.SetToZero();
00123 while(true)
00124 {
00125 map2alm(map2,alm,wgt,true);
00126 alm2map(alm,map2);
00127 double errmeasure=0;
00128 for (int m=0; m<map.Npix(); ++m)
00129 {
00130 double err = abs(map[m]-map2[m]);
00131 double rel = (map[m]!=0) ? abs(err/map[m]) : 1e300;
00132 errmeasure = max(errmeasure,min(err*x_err_abs,rel*x_err_rel));
00133 map2[m] = map[m]-map2[m];
00134 }
00135 cout << "map error measure: " << errmeasure << endl;
00136 if (errmeasure<1) break;
00137 }
00138 }
00139
00140 template void map2alm_iter2 (const Healpix_Map<double> &map,
00141 Alm<xcomplex<double> > &alm, double err_abs, double err_rel);
00142
00143
00144 template<typename T> void map2alm_pol
00145 (const Healpix_Map<T> &mapT,
00146 const Healpix_Map<T> &mapQ,
00147 const Healpix_Map<T> &mapU,
00148 Alm<xcomplex<T> > &almT,
00149 Alm<xcomplex<T> > &almG,
00150 Alm<xcomplex<T> > &almC,
00151 const arr<double> &weight,
00152 bool add_alm)
00153 {
00154 planck_assert (mapT.Scheme()==RING,
00155 "map2alm_pol: maps must be in RING scheme");
00156 planck_assert (mapT.conformable(mapQ) && mapT.conformable(mapU),
00157 "map2alm_pol: maps are not conformable");
00158 planck_assert (weight.size()>=2*mapT.Nside(),
00159 "map2alm_pol: at least one weight array has too few entries");
00160
00161 vector<ringpair> pair;
00162 healpix2ringpairs(mapT,weight,pair);
00163 map2alm_pol(pair,&mapT[0],&mapQ[0],&mapU[0],almT,almG,almC,add_alm);
00164 }
00165
00166 template void map2alm_pol
00167 (const Healpix_Map<float> &mapT,
00168 const Healpix_Map<float> &mapQ,
00169 const Healpix_Map<float> &mapU,
00170 Alm<xcomplex<float> > &almT,
00171 Alm<xcomplex<float> > &almG,
00172 Alm<xcomplex<float> > &almC,
00173 const arr<double> &weight,
00174 bool add_alm);
00175 template void map2alm_pol
00176 (const Healpix_Map<double> &mapT,
00177 const Healpix_Map<double> &mapQ,
00178 const Healpix_Map<double> &mapU,
00179 Alm<xcomplex<double> > &almT,
00180 Alm<xcomplex<double> > &almG,
00181 Alm<xcomplex<double> > &almC,
00182 const arr<double> &weight,
00183 bool add_alm);
00184
00185 template<typename T> void map2alm_pol_iter
00186 (const Healpix_Map<T> &mapT,
00187 const Healpix_Map<T> &mapQ,
00188 const Healpix_Map<T> &mapU,
00189 Alm<xcomplex<T> > &almT,
00190 Alm<xcomplex<T> > &almG,
00191 Alm<xcomplex<T> > &almC,
00192 int num_iter,
00193 const arr<double> &weight)
00194 {
00195 map2alm_pol(mapT,mapQ,mapU,almT,almG,almC,weight);
00196 for (int iter=1; iter<=num_iter; ++iter)
00197 {
00198 Healpix_Map<T> mapT2(mapT.Nside(),mapT.Scheme(),SET_NSIDE),
00199 mapQ2(mapT.Nside(),mapT.Scheme(),SET_NSIDE),
00200 mapU2(mapT.Nside(),mapT.Scheme(),SET_NSIDE);
00201
00202 alm2map_pol(almT,almG,almC,mapT2,mapQ2,mapU2);
00203 for (int m=0; m<mapT.Npix(); ++m)
00204 {
00205 mapT2[m] = mapT[m]-mapT2[m];
00206 mapQ2[m] = mapQ[m]-mapQ2[m];
00207 mapU2[m] = mapU[m]-mapU2[m];
00208 }
00209 map2alm_pol(mapT2,mapQ2,mapU2,almT,almG,almC,weight,true);
00210 }
00211 }
00212
00213 template void map2alm_pol_iter
00214 (const Healpix_Map<float> &mapT,
00215 const Healpix_Map<float> &mapQ,
00216 const Healpix_Map<float> &mapU,
00217 Alm<xcomplex<float> > &almT,
00218 Alm<xcomplex<float> > &almG,
00219 Alm<xcomplex<float> > &almC,
00220 int num_iter,
00221 const arr<double> &weight);
00222 template void map2alm_pol_iter
00223 (const Healpix_Map<double> &mapT,
00224 const Healpix_Map<double> &mapQ,
00225 const Healpix_Map<double> &mapU,
00226 Alm<xcomplex<double> > &almT,
00227 Alm<xcomplex<double> > &almG,
00228 Alm<xcomplex<double> > &almC,
00229 int num_iter,
00230 const arr<double> &weight);
00231
00232 template<typename T> void map2alm_pol_iter2
00233 (const Healpix_Map<T> &mapT,
00234 const Healpix_Map<T> &mapQ,
00235 const Healpix_Map<T> &mapU,
00236 Alm<xcomplex<T> > &almT,
00237 Alm<xcomplex<T> > &almG,
00238 Alm<xcomplex<T> > &almC,
00239 double err_abs, double err_rel)
00240 {
00241 arr<double> wgt(2*mapT.Nside());
00242 wgt.fill(1);
00243 Healpix_Map<T> mapT2(mapT), mapQ2(mapQ), mapU2(mapU);
00244 almT.SetToZero(); almG.SetToZero(); almC.SetToZero();
00245 while(true)
00246 {
00247 map2alm_pol(mapT2,mapQ2,mapU2,almT,almG,almC,wgt,true);
00248 alm2map_pol(almT,almG,almC,mapT2,mapQ2,mapU2);
00249 double errmeasure=0;
00250 for (int m=0; m<mapT.Npix(); ++m)
00251 {
00252 double err = abs(mapT[m]-mapT2[m]);
00253 double rel = (mapT[m]!=0) ? abs(err/mapT[m]) : 1e300;
00254 errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
00255 mapT2[m] = mapT[m]-mapT2[m];
00256 err = abs(mapQ[m]-mapQ2[m]);
00257 rel = (mapQ[m]!=0) ? abs(err/mapQ[m]) : 1e300;
00258 errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
00259 mapQ2[m] = mapQ[m]-mapQ2[m];
00260 err = abs(mapU[m]-mapU2[m]);
00261 rel = (mapU[m]!=0) ? abs(err/mapU[m]) : 1e300;
00262 errmeasure = max(errmeasure,min(err/err_abs,rel/err_rel));
00263 mapU2[m] = mapU[m]-mapU2[m];
00264 }
00265 cout << "map error measure: " << errmeasure << endl;
00266 if (errmeasure<1) break;
00267 }
00268 }
00269
00270 template void map2alm_pol_iter2
00271 (const Healpix_Map<double> &mapT,
00272 const Healpix_Map<double> &mapQ,
00273 const Healpix_Map<double> &mapU,
00274 Alm<xcomplex<double> > &almT,
00275 Alm<xcomplex<double> > &almG,
00276 Alm<xcomplex<double> > &almC,
00277 double err_abs, double err_rel);
00278
00279
00280 template<typename T> void alm2map (const Alm<xcomplex<T> > &alm,
00281 Healpix_Map<T> &map)
00282 {
00283 planck_assert (map.Scheme()==RING, "alm2map: map must be in RING scheme");
00284
00285 vector<ringpair> pair;
00286 healpix2ringpairs(map,pair);
00287 alm2map(alm,pair,&map[0]);
00288 }
00289
00290 template void alm2map (const Alm<xcomplex<double> > &alm,
00291 Healpix_Map<double> &map);
00292 template void alm2map (const Alm<xcomplex<float> > &alm,
00293 Healpix_Map<float> &map);
00294
00295
00296 template<typename T> void alm2map_pol
00297 (const Alm<xcomplex<T> > &almT,
00298 const Alm<xcomplex<T> > &almG,
00299 const Alm<xcomplex<T> > &almC,
00300 Healpix_Map<T> &mapT,
00301 Healpix_Map<T> &mapQ,
00302 Healpix_Map<T> &mapU)
00303 {
00304 planck_assert (mapT.Scheme()==RING,
00305 "alm2map_pol: maps must be in RING scheme");
00306 planck_assert (mapT.conformable(mapQ) && mapT.conformable(mapU),
00307 "alm2map_pol: maps are not conformable");
00308
00309 vector<ringpair> pair;
00310 healpix2ringpairs(mapT,pair);
00311 alm2map_pol(almT,almG,almC,pair,&mapT[0],&mapQ[0],&mapU[0]);
00312 }
00313
00314 template void alm2map_pol (const Alm<xcomplex<double> > &almT,
00315 const Alm<xcomplex<double> > &almG,
00316 const Alm<xcomplex<double> > &almC,
00317 Healpix_Map<double> &mapT,
00318 Healpix_Map<double> &mapQ,
00319 Healpix_Map<double> &mapU);
00320
00321 template void alm2map_pol (const Alm<xcomplex<float> > &almT,
00322 const Alm<xcomplex<float> > &almG,
00323 const Alm<xcomplex<float> > &almC,
00324 Healpix_Map<float> &mapT,
00325 Healpix_Map<float> &mapQ,
00326 Healpix_Map<float> &mapU);
00327
00328
00329 template<typename T> void alm2map_der1
00330 (const Alm<xcomplex<T> > &alm,
00331 Healpix_Map<T> &map,
00332 Healpix_Map<T> &mapdth,
00333 Healpix_Map<T> &mapdph)
00334 {
00335 planck_assert (map.Scheme()==RING,
00336 "alm2map_der1: maps must be in RING scheme");
00337 planck_assert (map.conformable(mapdth) && map.conformable(mapdph),
00338 "alm2map_der1: maps are not conformable");
00339
00340 vector<ringpair> pair;
00341 healpix2ringpairs(map,pair);
00342 alm2map_der1(alm,pair,&map[0],&mapdth[0],&mapdph[0]);
00343 }
00344
00345 template void alm2map_der1 (const Alm<xcomplex<double> > &alm,
00346 Healpix_Map<double> &map,
00347 Healpix_Map<double> &map_dth,
00348 Healpix_Map<double> &map_dph);
00349
00350 template void alm2map_der1 (const Alm<xcomplex<float> > &alm,
00351 Healpix_Map<float> &map,
00352 Healpix_Map<float> &map_dth,
00353 Healpix_Map<float> &map_dph);