hpxtest.cc

00001 /*
00002  *  This file is part of Healpix_cxx.
00003  *
00004  *  Healpix_cxx is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  Healpix_cxx is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with Healpix_cxx; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  *  For more information about HEALPix, see http://healpix.sourceforge.net
00019  */
00020 
00021 /*
00022  *  Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
00023  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
00024  *  (DLR).
00025  */
00026 
00027 /*
00028  *  Copyright (C) 2004-2015 Max-Planck-Society
00029  *  Author: Martin Reinecke
00030  */
00031 
00032 /*
00033 
00034 Candidates for testing the validity of the Healpix routines:
00035 
00036 - done: ang2pix(pix2ang(i)) = i for all Healpix_Bases
00037 - done: pix2ang(ang2pix(ptg)) dot ptg > 1-delta for all Healpix_Bases
00038 - done: ring2nest(nest2ring(i)) = i for all hierarchical Healpix_Bases
00039 - done: downgrade(upgrade(map)) = map for all maps
00040 - done: map and downgraded map should have same average
00041 - done: alm2map(map2alm(map)) approx map (same for pol)
00042 - partly done: neighbor tests
00043 - powspec -> alm -> powspec (should produce similar powspecs, also for pol)
00044 - done: two swap_schemes() should produce original map
00045 - done: query_disc tests (dot products etc.)
00046 - a_lms: test Set(), Scale(), Add(), alm(l,m) = alm.mstart(m)[l], etc.
00047 
00048 */
00049 
00050 #include <iostream>
00051 #include "healpix_base.h"
00052 #include "healpix_map.h"
00053 #include "arr.h"
00054 #include "planck_rng.h"
00055 #include "lsconstants.h"
00056 #include "alm.h"
00057 #include "alm_healpix_tools.h"
00058 #include "alm_powspec_tools.h"
00059 #include "geom_utils.h"
00060 #include "walltimer.h"
00061 #include "announce.h"
00062 #include "compress_utils.h"
00063 #include "moc.h"
00064 #include "moc_fitsio.h"
00065 
00066 using namespace std;
00067 
00068 #define UNITTESTS
00069 
00070 #ifdef UNITTESTS
00071 int errcount=0;
00072 #define FAIL(a) {a; if (++errcount>100) planck_fail("unit test errors");}
00073 #else
00074 #define FAIL(a) a;
00075 #endif
00076 
00077 const int nsamples = 1000000;
00078 
00079 planck_rng rng;
00080 
00081 namespace {
00082 
00083 void random_dir (pointing &ptg)
00084   {
00085   ptg.theta = acos(rng.rand_uni()*2-1);
00086   ptg.phi = rng.rand_uni()*twopi;
00087   }
00088 void random_zphi (double &z, double &phi)
00089   {
00090   z = rng.rand_uni()*2-1;
00091   phi = rng.rand_uni()*twopi;
00092   }
00093 
00094 template<typename I> string bname()
00095   { return string("(basetype: ")+type2typename<I>()+")"; }
00096 
00097 
00098 template<typename I> rangeset<I> randomRangeSet(int num, I start, int dist)
00099   {
00100   rangeset<I> rs;
00101   I curval=start;
00102   for (int i=0; i<num; ++i)
00103     {
00104     I v1=curval+1+(rng.int_rand_uni()%dist);
00105     I v2=v1+1+(rng.int_rand_uni()%dist);
00106     rs.append(v1,v2);
00107     curval=v2;
00108     }
00109   return rs;
00110   }
00111 template<typename I> Moc<I> randomMoc(int num, I start, int dist)
00112   {
00113   Moc<I> moc;
00114   I curval=start+(I(1)<<(2*Moc<I>::maxorder));
00115   for (int i=0; i<num; ++i)
00116     {
00117     I v1=curval+1+(rng.int_rand_uni()%dist);
00118     I v2=v1+1+(rng.int_rand_uni()%dist);
00119     moc.addPixelRange(Moc<I>::maxorder,v1,v2);
00120     curval=v2;
00121     }
00122   return moc;
00123   }
00124 
00125 template<typename I> rangeset<I> makeRS(const string &input)
00126   {
00127   istringstream is(input);
00128   rangeset<I> res;
00129   I a,b;
00130   while (is)
00131     {
00132     is>>a>>b;
00133     planck_assert (is||is.eof(),"aargh");
00134     if (is) res.append(a,b);
00135     }
00136   return res;
00137   }
00138 template<typename I> void rsOps(const rangeset<I> &a, const rangeset<I> &b)
00139   {
00140   planck_assert(!b.overlaps(a.op_andnot(b)),"error");
00141   planck_assert(a.op_or(b).nval()>=a.nval(),"error");
00142   planck_assert(a.op_or(b).nval()>=b.nval(),"error");
00143   planck_assert(a.op_and(b).nval()<=a.nval(),"error");
00144   planck_assert(a.op_and(b).nval()<=b.nval(),"error");
00145   planck_assert(a.op_or(b).contains(a),"error");
00146   planck_assert(a.op_or(b).contains(b),"error");
00147   planck_assert(!a.op_andnot(b).overlaps(b),"error");
00148   planck_assert(!b.op_andnot(a).overlaps(a),"error");
00149   planck_assert(a.op_or(b).nval()==a.nval()+b.nval()-a.op_and(b).nval(),
00150     "error");
00151   planck_assert(a.op_or(b).op_andnot(a.op_and(b)).nval()==
00152                 a.op_or(b).nval()-a.op_and(b).nval(),"error");
00153   planck_assert(a.op_xor(b)==a.op_andnot(b).op_or(b.op_andnot(a)),"error");
00154   }
00155 template<typename I> void check_rangeset()
00156   {
00157   cout << "testing rangeset " << bname<I>() << endl;
00158   {
00159   rangeset<I> b;
00160   b.append(1,11);
00161   planck_assert(b==makeRS<I>("1 11"),"mismatch");
00162   b.append(10,15);
00163   planck_assert(b==makeRS<I>("1 15"),"mismatch");
00164   b.append(1,15);
00165   planck_assert(b==makeRS<I>("1 15"),"mismatch");
00166   b.append(7,15);
00167   planck_assert(b==makeRS<I>("1 15"),"mismatch");
00168   b.append(30,41);
00169 #if 0
00170   planck_assert(b==makeRS<I>("1 15 30 41"),"mismatch");
00171   try
00172     {
00173     b.append(29,31);
00174     planck_fail("Should have raised an IllegalArgumentException");
00175     }
00176   catch (PlanckError E) {}
00177 #endif
00178   }
00179   {
00180   rangeset<I> b=makeRS<I>("1 11 30 41");
00181   planck_assert(!b.contains(0),"error");
00182   planck_assert(b.contains(1),"error");
00183   planck_assert(b.contains(5),"error");
00184   planck_assert(b.contains(10),"error");
00185   planck_assert(!b.contains(11),"error");
00186   planck_assert(!b.contains(29),"error");
00187   planck_assert(b.contains(30),"error");
00188   planck_assert(b.contains(35),"error");
00189   planck_assert(b.contains(40),"error");
00190   planck_assert(!b.contains(41),"errror");
00191   }
00192   {
00193   rangeset<I> b;
00194   b.add(5, 11);
00195   planck_assert(b==makeRS<I>("5 11"),"error");
00196   b.add(1, 7);
00197   planck_assert(b==makeRS<I>("1 11"),"error");
00198   b.add(1, 11);
00199   planck_assert(b==makeRS<I>("1 11"),"error");
00200   b.add(30, 41);
00201   planck_assert(b==makeRS<I>("1 11 30 41"),"error");
00202   b.add(1, 11);
00203   planck_assert(b==makeRS<I>("1 11 30 41"),"error");
00204   b.add(-1,0);
00205   planck_assert(b==makeRS<I>("-1 0 1 11 30 41"),"error");
00206   b.add(-2,-1);
00207   planck_assert(b==makeRS<I>("-2 0 1 11 30 41"),"error");
00208   b.add(-2,-1);
00209   planck_assert(b==makeRS<I>("-2 0 1 11 30 41"),"error");
00210   b.add(2, 11);
00211   planck_assert(b==makeRS<I>("-2 0 1 11 30 41"),"error");
00212   b.add(1, 10);
00213   planck_assert(b==makeRS<I>("-2 0 1 11 30 41"),"error");
00214   b.add(15, 21);
00215   planck_assert(b==makeRS<I>("-2 0 1 11 15 21 30 41"),"error");
00216   }
00217   {
00218   rangeset<I> b = makeRS<I>("0 11 20 31");
00219   b.remove(5,25);
00220   planck_assert(b==makeRS<I>("0 5 25 31"),"error");
00221   b.remove(31,32);
00222   planck_assert(b==makeRS<I>("0 5 25 31"),"error");
00223   b.remove(35,38);
00224   planck_assert(b==makeRS<I>("0 5 25 31"),"error");
00225   b.remove(-90,-80);
00226   planck_assert(b==makeRS<I>("0 5 25 31"),"error");
00227   b.remove(27,29);
00228   planck_assert(b==makeRS<I>("0 5 25 27 29 31"),"error");
00229   b.remove(25,26);
00230   planck_assert(b==makeRS<I>("0 5 26 27 29 31"),"error");
00231   b.remove(4,6);
00232   planck_assert(b==makeRS<I>("0 4 26 27 29 31"),"error");
00233   b.remove(-20,40);
00234   planck_assert(b==makeRS<I>(""),"error");
00235   b.remove(-20,40);
00236   planck_assert(b==makeRS<I>(""),"error");
00237   }
00238   {
00239   rangeset<I> b = makeRS<I>("0 11 20 31");
00240   b.intersect(2,29);
00241   planck_assert(b==makeRS<I>("2 11 20 29"),"error");
00242   b.intersect(-8,50);
00243   planck_assert(b==makeRS<I>("2 11 20 29"),"error");
00244   b.intersect(2,50);
00245   planck_assert(b==makeRS<I>("2 11 20 29"),"error");
00246   b.intersect(2,29);
00247   planck_assert(b==makeRS<I>("2 11 20 29"),"error");
00248   b.intersect(-18,29);
00249   planck_assert(b==makeRS<I>("2 11 20 29"),"error");
00250   b.intersect(3,11);
00251   planck_assert(b==makeRS<I>("3 11"),"error");
00252   b = makeRS<I>("0 11 20 31");
00253   b.intersect(3,15);
00254   planck_assert(b==makeRS<I>("3 11"),"error");
00255   b = makeRS<I>("0 11 20 31");
00256   b.intersect(17,30);
00257   planck_assert(b==makeRS<I>("20 30"),"error");
00258   b = makeRS<I>("0 11 20 31");
00259   b.intersect(11,20);
00260   planck_assert(b==makeRS<I>(""),"error");
00261   b = makeRS<I>("0 11 20 31");
00262   b.intersect(-8,-7);
00263   planck_assert(b==makeRS<I>(""),"error");
00264   b = makeRS<I>("0 11 20 31");
00265   b.intersect(31,35);
00266   planck_assert(b==makeRS<I>(""),"error");
00267   }
00268   {
00269   planck_assert(makeRS<I>("1 11 20 31 40 56")==
00270                 makeRS<I>("20 31 40 51").op_or
00271                 (makeRS<I>("1 11 45 56")),"error");
00272   planck_assert(makeRS<I>("1 11 45 56")==
00273                 makeRS<I>("").op_or
00274                 (makeRS<I>("1 11 45 56")),"error");
00275   planck_assert(makeRS<I>("1 11 45 56")==
00276                 makeRS<I>("1 11 45 56").op_or
00277                 (makeRS<I>("")),"error");
00278   }
00279   {
00280   planck_assert(makeRS<I>("22 24 45 51")==
00281                 makeRS<I>("20 31 40 51").op_and
00282                 (makeRS<I>("1 11 22 24 45 56")),"error");
00283   planck_assert(makeRS<I>("20 31 40 51 90 101 110 121 200 201")==
00284                 makeRS<I>("10 101 110 121 200 221").op_and
00285                 (makeRS<I>("20 31 40 51 90 201")),"error");
00286   planck_assert(makeRS<I>("")==
00287                 makeRS<I>("20 31 40 51").op_and
00288                 (makeRS<I>("")),"error");
00289   planck_assert(makeRS<I>("")==
00290                 makeRS<I>("").op_and
00291                 (makeRS<I>("20 31 40 51")),"error");
00292   }
00293   {
00294   planck_assert(makeRS<I>("20 31 40 45")==
00295                 makeRS<I>("20 31 40 51").op_andnot
00296                 (makeRS<I>("1 11 45 56")),"error");
00297   planck_assert(makeRS<I>("")==
00298                 makeRS<I>("").op_andnot
00299                 (makeRS<I>("1 11 45 56")),"error");
00300   planck_assert(makeRS<I>("1 11 45 56")==
00301                 makeRS<I>("1 11 45 56").op_andnot
00302                 (makeRS<I>("")),"error");
00303   }
00304   {
00305   rangeset<I> b = makeRS<I>("20 31 40 51");
00306 
00307   planck_assert(!b.contains(0,11),"error");
00308   planck_assert(!b.contains(10,21),"error");
00309   planck_assert(!b.contains(19,20),"error");
00310   planck_assert(b.contains(20,21),"error");
00311   planck_assert(b.contains(21,22),"error");
00312   planck_assert(b.contains(20,31),"error");
00313   planck_assert(!b.contains(25,36),"error");
00314   planck_assert(b.contains(30,31),"error");
00315   planck_assert(!b.contains(31,32),"error");
00316   planck_assert(!b.contains(35,38),"error");
00317   planck_assert(!b.contains(35,46),"error");
00318   planck_assert(b.contains(40,41),"error");
00319   planck_assert(!b.contains(45,56),"error");
00320   planck_assert(!b.contains(60,71),"error");
00321   }
00322   {
00323   rangeset<I> b = makeRS<I>("20 31 40 51");
00324 
00325   planck_assert(b.contains(makeRS<I>("20 31 40 51")),"error");
00326   planck_assert(b.contains(makeRS<I>("20 21")),"error");
00327   planck_assert(b.contains(makeRS<I>("50 51")),"error");
00328   planck_assert(!b.contains(makeRS<I>("19 31 40 51")),"error");
00329   planck_assert(!b.contains(makeRS<I>("20 31 40 52")),"error");
00330   planck_assert(!b.contains(makeRS<I>("20 51")),"error");
00331   planck_assert(!b.contains(makeRS<I>("0 1")),"error");
00332   planck_assert(!b.contains(makeRS<I>("0 20 31 40 51 100")),"error");
00333   }
00334   {
00335   rangeset<I> b = makeRS<I>("20 31 40 51");
00336 
00337   planck_assert(!b.overlaps(0,11),"error");
00338   planck_assert(b.overlaps(10,21),"error");
00339   planck_assert(!b.overlaps(19,20),"error");
00340   planck_assert(b.overlaps(20,21),"error");
00341   planck_assert(b.overlaps(21,22),"error");
00342   planck_assert(b.overlaps(20,31),"error");
00343   planck_assert(b.overlaps(25,36),"error");
00344   planck_assert(b.overlaps(30,37),"error");
00345   planck_assert(!b.overlaps(31,32),"error");
00346   planck_assert(!b.overlaps(35,38),"error");
00347   planck_assert(b.overlaps(35,46),"error");
00348   planck_assert(b.overlaps(40,41),"error");
00349   planck_assert(b.overlaps(45,56),"error");
00350   planck_assert(!b.overlaps(60,71),"error");
00351   }
00352   {
00353   rangeset<I> b = makeRS<I>("20 31 40 51");
00354 
00355   planck_assert(b.overlaps(makeRS<I>("20 31 40 51")),"error");
00356   planck_assert(b.overlaps(makeRS<I>("20 21")),"error");
00357   planck_assert(b.overlaps(makeRS<I>("50 51")),"error");
00358   planck_assert(b.overlaps(makeRS<I>("19 31 40 51")),"error");
00359   planck_assert(b.overlaps(makeRS<I>("20 31 40 52")),"error");
00360   planck_assert(b.overlaps(makeRS<I>("20 51")),"error");
00361   planck_assert(!b.overlaps(makeRS<I>("0 1")),"error");
00362   planck_assert(!b.overlaps(makeRS<I>("0 20 31 40 51 100")),"error");
00363   }
00364   {
00365   const int niter = 1000;
00366   for (int iter=0; iter<niter; ++iter)
00367     {
00368     rangeset<I> a = randomRangeSet<I>(1000, 0, 100);
00369     rangeset<I> b = randomRangeSet<I>(1000, 0, 100);
00370     rangeset<I> c = randomRangeSet<I>(10, 10000, 100);
00371     rsOps(a,b);
00372     rsOps(a,c);
00373     rsOps(c,a);
00374     }
00375   }
00376   }
00377 template<typename I> void check_Moc()
00378   {
00379   cout << "testing MOC " << bname<I>() << endl;
00380   Moc<I> moc;
00381   moc.addPixelRange(0,4,5);
00382   moc.addPixelRange(0,6,7);
00383   moc.addPixelRange(2,4,17);
00384   moc.addPixelRange(10,3000000,3000001);
00385 
00386   planck_assert(moc==moc.complement().complement(),"error");
00387   planck_assert(moc==Moc<I>::fromUniq(moc.toUniq()),"error");
00388   planck_assert(moc.maxOrder()==10,"error");
00389   Moc<I> xtmp = moc.degradedToOrder(8,false);
00390   planck_assert(moc.contains(xtmp),"error");
00391   planck_assert(!xtmp.contains(moc),"error");
00392   planck_assert(xtmp.overlaps(moc),"error");
00393   xtmp=moc.degradedToOrder(8,true);
00394   planck_assert(!moc.contains(xtmp),"error");
00395   planck_assert(xtmp.contains(moc),"error");
00396   planck_assert(xtmp.overlaps(moc),"error");
00397   planck_assert(moc==Moc<I>::fromCompressed(moc.toCompressed()),"error");
00398 #if 0
00399   assertEquals("inconsistency",moc,MocUtil.mocFromString(" 0/4, 6 2/ \t 4 -16 10/3000000 \t\n "));
00400   assertEquals("inconsistency",moc,MocUtil.mocFromString("0/6 2/ 5 2/4 2/6- 16 0/4  10/3000000"));
00401   assertEquals("inconsistency",moc,MocUtil.mocFromString
00402     ("{\"0\":[6] , \"2\": [5 ], \"2\":[  4,6,7,8,9,10,11,12,13,14,15,16], \"0\":[4],  \"10\":[3000000]}"));
00403   assertEquals("inconsistency",moc,MocUtil.mocFromString(MocUtil.mocToStringASCII(moc)));
00404   assertEquals("inconsistency",moc,MocUtil.mocFromString(MocUtil.mocToStringJSON(moc)));
00405   ByteArrayOutputStream out= new ByteArrayOutputStream();
00406   MocUtil.mocToFits(moc,out);
00407   ByteArrayInputStream inp = new ByteArrayInputStream(out.toByteArray());
00408   assertEquals("inconsistency",moc,MocUtil.mocFromFits(inp));
00409 #endif
00410   {
00411   tsize niter = 100;
00412   Moc<I> full; full.addPixelRange(0,0,12);
00413   Moc<I> empty;
00414   for (tsize iter=0; iter<niter; ++iter)
00415     {
00416     Moc<I> a = randomMoc<I>(1000, 0, 100);
00417     planck_assert(a.complement().complement()==a,"error");
00418     planck_assert(!a.overlaps(a.complement()),"error");
00419     planck_assert(a.op_or(a.complement())==full,"error");
00420     planck_assert(a.op_and(a.complement())==empty,"error");
00421 #if 0
00422     write_Moc_to_fits("!healpixtestmoctmp",a);
00423     Moc<I> b;
00424     read_Moc_from_fits("healpixtestmoctmp",b);
00425     planck_assert(a==b,"FITS problem");
00426 #endif
00427     }
00428   }
00429   }
00430 template<typename I> void check_compress()
00431   {
00432   cout << "testing interpolation coding " << bname<I>() << endl;
00433   planck_assert(trailingZeros(4)==2,"error");
00434   planck_assert(trailingZeros(5)==0,"error");
00435   planck_assert(trailingZeros(int64(1)<<48)==48,"error");
00436   for (tsize x=0; x<100; ++x)
00437     {
00438     rangeset<I> a = randomRangeSet<I>(1000, 0, 100);
00439     rangeset<I> b;
00440     for (tsize i=0; i<a.nranges(); ++i)
00441       b.append(a.ivbegin(i)<<6,a.ivend(i)<<6);
00442     const vector<I> &v=b.data();
00443     obitstream obs;
00444     interpol_encode(v.begin(),v.end(),obs);
00445     vector<uint8> comp=obs.state();
00446     vector<I> v2;
00447     ibitstream ibs(comp);
00448     interpol_decode(v2,ibs);
00449     planck_assert(v==v2,"data mismatch");
00450     }
00451   }
00452 
00453 template<typename I> void check_ringnestring()
00454   {
00455   cout << "testing ring2nest(nest2ring(m))==m " << bname<I>() << endl;
00456   for (int order=0; order<=T_Healpix_Base<I>::order_max; ++order)
00457     {
00458     T_Healpix_Base<I> base (order,RING);
00459     for (int m=0; m<nsamples; ++m)
00460       {
00461       I pix = I(rng.rand_uni()*base.Npix());
00462       if (base.ring2nest(base.nest2ring(pix))!=pix)
00463         FAIL(cout<<"  PROBLEM: order = "<<order<<", pixel = "<<pix<<endl)
00464       }
00465     }
00466   }
00467 
00468 template<typename I> void check_nestpeanonest()
00469   {
00470   cout << "testing peano2nest(nest2peano(m))==m " << bname<I>() << endl;
00471   for (int order=0; order<=T_Healpix_Base<I>::order_max; ++order)
00472     {
00473     T_Healpix_Base<I> base (order,NEST);
00474     for (int m=0; m<nsamples; ++m)
00475       {
00476       I pix = I(rng.rand_uni()*base.Npix());
00477       if (base.peano2nest(base.nest2peano(pix))!=pix)
00478         FAIL(cout<<"  PROBLEM: order = "<<order<<", pixel = "<<pix<<endl)
00479       }
00480     }
00481   }
00482 
00483 template<typename I> void check_pixzphipix()
00484   {
00485   cout << "testing zphi2pix(pix2zphi(m))==m " << bname<I>() << endl;
00486   int omax=T_Healpix_Base<I>::order_max;
00487   for (int order=0; order<=omax; ++order)
00488     {
00489     T_Healpix_Base<I> base1 (order,RING), base2 (order,NEST);
00490     for (int m=0; m<nsamples; ++m)
00491       {
00492       double z,phi;
00493       I pix = I(rng.rand_uni()*base1.Npix());
00494       base1.pix2zphi(pix,z,phi);
00495       if (base1.zphi2pix(z,phi)!=pix)
00496         FAIL(cout<<"  PROBLEM: order = "<<order<<", pixel = "<<pix<<endl)
00497       base2.pix2zphi(pix,z,phi);
00498       if (base2.zphi2pix(z,phi)!=pix)
00499         FAIL(cout<<"  PROBLEM: order = "<<order<<", pixel = "<<pix<<endl)
00500       }
00501     }
00502   for (I nside=3; nside<(I(1)<<omax); nside+=nside/2+1)
00503     {
00504     T_Healpix_Base<I> base (nside,RING,SET_NSIDE);
00505     for (int m=0; m<nsamples; ++m)
00506       {
00507       double z,phi;
00508       I pix = I(rng.rand_uni()*base.Npix());
00509       base.pix2zphi(pix,z,phi);
00510       if (base.zphi2pix(z,phi)!=pix)
00511         FAIL(cout<<"  PROBLEM: nside = "<<nside<<", pixel = "<<pix<<endl)
00512       }
00513     }
00514   }
00515 
00516 template<typename I> void check_zphipixzphi()
00517   {
00518   cout << "testing pix2zphi(zphi2pix(ptg)) approx zphi " << bname<I>() << endl;
00519   int omax=T_Healpix_Base<I>::order_max;
00520   for (int order=0; order<=omax; ++order)
00521     {
00522     T_Healpix_Base<I> base1 (order,NEST), base2 (order,RING);
00523     double mincos = min (cos(base1.max_pixrad()),0.999999999999999);
00524     for (int m=0; m<nsamples; ++m)
00525       {
00526       double z,phi,z2,phi2;
00527       random_zphi (z,phi);
00528       base1.pix2zphi(base1.zphi2pix(z,phi),z2,phi2);
00529       if (cosdist_zphi(z,phi,z2,phi2)<mincos)
00530         FAIL(cout << "  PROBLEM: order = " << order
00531                   << ", zphi = " << z << ", " << phi << endl)
00532       base2.pix2zphi(base2.zphi2pix(z,phi),z2,phi2);
00533       if (cosdist_zphi(z,phi,z2,phi2)<mincos)
00534         FAIL(cout << "  PROBLEM: order = " << order
00535                   << ", zphi = " << z << ", " << phi << endl)
00536       }
00537     }
00538   for (int nside=3; nside<(I(1)<<omax); nside+=nside/2+1)
00539     {
00540     T_Healpix_Base<I> base (nside,RING,SET_NSIDE);
00541     double mincos = min (cos(base.max_pixrad()),0.999999999999999);
00542     for (int m=0; m<nsamples; ++m)
00543       {
00544       double z,phi,z2,phi2;
00545       random_zphi (z,phi);
00546       base.pix2zphi(base.zphi2pix(z,phi),z2,phi2);
00547       if (cosdist_zphi(z,phi,z2,phi2)<mincos)
00548         FAIL(cout << "  PROBLEM: nside = " << nside
00549                   << ", zphi = " << z << ", " << phi << endl)
00550       }
00551     }
00552   }
00553 
00554 template<typename I> void check_pixangpix()
00555   {
00556   cout << "testing ang2pix(pix2ang(m))==m " << bname<I>() << endl;
00557   int omax=T_Healpix_Base<I>::order_max;
00558   for (int order=0; order<=omax; ++order)
00559     {
00560     T_Healpix_Base<I> base1 (order,RING), base2 (order,NEST);
00561     for (int m=0; m<nsamples; ++m)
00562       {
00563       I pix = I(rng.rand_uni()*base1.Npix());
00564       if (base1.ang2pix(base1.pix2ang(pix))!=pix)
00565         FAIL(cout<<"  PROBLEM: order = "<<order<<", pixel = "<<pix<<endl)
00566       if (base2.ang2pix(base2.pix2ang(pix))!=pix)
00567         FAIL(cout<<"  PROBLEM: order = "<<order<<", pixel = "<<pix<<endl)
00568       }
00569     }
00570   for (I nside=3; nside<(I(1)<<omax); nside+=nside/2+1)
00571     {
00572     T_Healpix_Base<I> base (nside,RING,SET_NSIDE);
00573     for (int m=0; m<nsamples; ++m)
00574       {
00575       I pix = I(rng.rand_uni()*base.Npix());
00576       if (base.ang2pix(base.pix2ang(pix))!=pix)
00577         FAIL(cout<<"  PROBLEM: nside = "<<nside<<", pixel = "<<pix<<endl)
00578       }
00579     }
00580   }
00581 
00582 template<typename I> void check_neighbors()
00583   {
00584   cout << "testing neighbor function " << bname<I>() << endl;
00585   int omax=T_Healpix_Base<I>::order_max;
00586   for (int order=0; order<=omax; ++order)
00587     {
00588     T_Healpix_Base<I> base (order,NEST), base2(order,RING);
00589     double maxang = 2.01*base.max_pixrad();
00590     for (int m=0; m<nsamples/10; ++m)
00591       {
00592       I pix = I(rng.rand_uni()*base.Npix());
00593       fix_arr<I,8> nb,nb2;
00594       vec3 pixpt = base.pix2vec(pix);
00595       base.neighbors(pix,nb);
00596       base2.neighbors(base.nest2ring(pix),nb2);
00597       for (int n=0; n<8; ++n)
00598         if (nb[n]<0)
00599           planck_assert(nb2[n]<0,"neighbor inconsistency");
00600         else
00601           planck_assert(base.nest2ring(nb[n])==nb2[n],"neighbor inconsistency");
00602       sort(&nb[0],&nb[0]+8);
00603       int check=0;
00604       for (int n=0; n<8; ++n)
00605         {
00606         if (nb[n]<0)
00607           ++check;
00608         else
00609           {
00610           if (v_angle(base.pix2vec(nb[n]),pixpt)>maxang)
00611             FAIL(cout<<"  PROBLEM: order = "<<order<<", pix = "<<pix<<endl)
00612           if ((n>0) && (nb[n]==nb[n-1]))
00613             FAIL(cout<<"  PROBLEM: order = "<<order<<", pix = "<<pix<<endl)
00614           }
00615         }
00616       planck_assert((check<=1)||((order==0)&&(check<=2)),"too few neighbors");
00617       }
00618     }
00619   for (I nside=3; nside<(I(1)<<omax); nside+=nside/2+1)
00620     {
00621     T_Healpix_Base<I> base (nside,RING,SET_NSIDE);
00622     double maxang = 2.01*base.max_pixrad();
00623     for (int m=0; m<nsamples/10; ++m)
00624       {
00625       I pix = I(rng.rand_uni()*base.Npix());
00626       fix_arr<I,8> nb;
00627       vec3 pixpt = base.pix2vec(pix);
00628       base.neighbors(pix,nb);
00629       for (int n=0; n<8; ++n)
00630         if ((nb[n]>=0) && (v_angle(base.pix2vec(nb[n]),pixpt)>maxang))
00631           FAIL(cout<<"  PROBLEM: nside = "<<nside<<", pix = "<<pix<<endl)
00632       }
00633     }
00634   }
00635 
00636 void check_swap_scheme()
00637   {
00638   cout << "testing whether double swap_scheme() returns the original map"
00639        << endl << "(for orders 0 to 10)." << endl;
00640   for (int order=0; order<=10; ++order)
00641     {
00642     Healpix_Map<uint8> map(order,NEST);
00643     for (int m=0; m<map.Npix(); ++m) map[m]=uint8(m&0xFF);
00644     map.swap_scheme();
00645     map.swap_scheme();
00646     for (int m=0; m<map.Npix(); ++m)
00647       if (map[m]!=(m&0xFF))
00648         FAIL(cout<<"  PROBLEM: order = "<<order<<", pix = "<<m<<endl)
00649     }
00650   }
00651 
00652 void check_issue_229 (Healpix_Ordering_Scheme scheme)
00653   {
00654   cout << "checking issue #229" << endl;
00655   int order=8;
00656   Healpix_Map<bool> map (order,scheme);
00657   map.fill(false);
00658   Healpix_Map<vec3> vmap(order,scheme);
00659   for (int m=0; m<vmap.Npix(); ++m)
00660     vmap[m]=vmap.pix2vec(m);
00661   rangeset<int> pixset;
00662   pointing ptg(halfpi-0.1,0);
00663   double rad=0.1;
00664   map.query_disc(ptg,rad,pixset);
00665   vec3 vptg=ptg;
00666   double cosrad=cos(rad);
00667   for (tsize j=0; j<pixset.nranges(); ++j)
00668     for (int i=pixset.ivbegin(j); i<pixset.ivend(j); ++i)
00669       map[i] = true;
00670   for (int i=0; i<map.Npix(); ++i)
00671     {
00672     bool inside = dotprod(vmap[i],vptg)>cosrad;
00673     if (inside^map[i])
00674       FAIL(cout << "  PROBLEM: issue 229" << endl)
00675     }
00676   }
00677 
00678 void check_query_disc_strict (Healpix_Ordering_Scheme scheme)
00679   {
00680   cout << "testing whether all pixels found by query_disc() really" << endl
00681        << "lie inside the disk (and vice versa)" << endl;
00682   cout << "Ordering scheme: " << (scheme==RING ? "RING" : "NEST") << endl;
00683   rng.seed(42);
00684   for (int order=0; order<=5; ++order)
00685     {
00686     Healpix_Map<bool> map (order,scheme);
00687     map.fill(false);
00688     Healpix_Map<vec3> vmap(order,scheme);
00689     for (int m=0; m<vmap.Npix(); ++m)
00690       vmap[m]=vmap.pix2vec(m);
00691     rangeset<int> pixset;
00692     for (int m=0; m<100000; ++m)
00693       {
00694       pointing ptg;
00695       random_dir (ptg);
00696       double rad = pi/1 * rng.rand_uni();
00697       map.query_disc(ptg,rad,pixset);
00698       vec3 vptg=ptg;
00699       double cosrad=cos(rad);
00700       for (tsize j=0; j<pixset.nranges(); ++j)
00701         for (int i=pixset.ivbegin(j); i<pixset.ivend(j); ++i)
00702           map[i] = true;
00703       for (int i=0; i<map.Npix(); ++i)
00704         {
00705         bool inside = dotprod(vmap[i],vptg)>cosrad;
00706         if (inside^map[i])
00707           FAIL(cout<<"  PROBLEM: order = "<<order<<", ptg = "<<ptg<<endl)
00708         }
00709       for (tsize j=0; j<pixset.nranges(); ++j)
00710         for (int i=pixset.ivbegin(j); i<pixset.ivend(j); ++i)
00711           map[i] = false;
00712       }
00713     }
00714   }
00715 
00716 template<typename I>void check_query_disc()
00717   {
00718   cout << "checking query_disc() " << bname<I>() << endl;
00719   rng.seed(48);
00720   int omax=min<int>(20,T_Healpix_Base<I>::order_max);
00721   for (int order=0; order<=omax; ++order)
00722     {
00723     T_Healpix_Base<I> rbase (order,RING), nbase (order,NEST);
00724     rangeset<I> pixset;
00725     int niter=max(1,min(1000,100000>>order));
00726     for (int m=0; m<niter; ++m)
00727       {
00728       pointing ptg;
00729       random_dir (ptg);
00730       double rad = pi/1 * rng.rand_uni();
00731       rbase.query_disc(ptg,rad,pixset);
00732       rangeset<I> pslast=pixset;
00733       for (tsize fct=5; fct>0; --fct)
00734         {
00735         rangeset<I> psi;
00736         rbase.query_disc_inclusive(ptg,rad,psi,fct);
00737         if (!psi.contains(pslast))
00738           cout << "  Potential problem: RING pixel sets inconsistent" << endl;
00739         swap(pslast,psi);
00740         }
00741       I nval = pixset.nval();
00742       nbase.query_disc(ptg,rad,pixset);
00743       pslast=pixset;
00744       for (tsize fct=8; fct>0; fct>>=1)
00745         {
00746         rangeset<I> psi;
00747         nbase.query_disc_inclusive(ptg,rad,psi,fct);
00748         if (!psi.contains(pslast))
00749           FAIL(cout << "  PROBLEM: NEST pixel sets inconsistent" << endl)
00750         swap(pslast,psi);
00751         }
00752       if (nval!=pixset.nval())
00753         FAIL(cout << "  PROBLEM: number of pixels different: "
00754                   << nval << " vs. " << pixset.nval() << endl)
00755       }
00756     }
00757   }
00758 template<typename I>void check_query_polygon()
00759   {
00760   cout << "checking query_polygon() " << bname<I>() << endl;
00761   rng.seed(42);
00762   int omax=min<int>(20,T_Healpix_Base<I>::order_max);
00763   for (int order=0; order<=omax; ++order)
00764     {
00765     T_Healpix_Base<I> rbase (order,RING), nbase (order,NEST);
00766     rangeset<I> pixset;
00767     int niter=max(1,min(1000,100000>>order));
00768     for (int m=0; m<niter; ++m)
00769       {
00770       vector<pointing> corner(3);
00771       random_dir(corner[0]); random_dir(corner[1]); random_dir(corner[2]);
00772       rbase.query_polygon(corner,pixset);
00773       I nval = pixset.nval();
00774       nbase.query_polygon(corner,pixset);
00775       if (nval!=pixset.nval())
00776         FAIL(cout << "  PROBLEM: number of pixels different: "
00777                   << nval << " vs. " << pixset.nval() << endl)
00778       rbase.query_polygon_inclusive(corner,pixset,4);
00779       I nv1=pixset.nval();
00780       nbase.query_polygon_inclusive(corner,pixset,4);
00781       I nv2=pixset.nval();
00782       if (nv1<nv2)
00783         FAIL(cout << "  PROBLEM: inclusive(RING)<inclusive(NEST): "
00784                   << nv1 << " vs. " << nv2 << endl)
00785       if (nv2<nval)
00786         FAIL(cout << "  PROBLEM: inclusive(NEST)<non-inclusive: "
00787                   << nv2 << " vs. " << nval << endl)
00788       }
00789     }
00790   }
00791 
00792 void helper_oop (int order)
00793   {
00794   Healpix_Map<double> map (order,RING), map2 (order,NEST), map3 (order,RING);
00795   for (int m=0; m<map.Npix(); ++m) map[m] = rng.rand_uni()+0.01;
00796   map2.Import(map);
00797   map3.Import(map2);
00798   for (int m=0; m<map.Npix(); ++m)
00799     if (!approx(map[m],map3[m],1e-12))
00800       FAIL(cout << "PROBLEM: order = " << order << endl)
00801   }
00802 void helper_udgrade (int order, Healpix_Ordering_Scheme s1,
00803   Healpix_Ordering_Scheme s2)
00804   {
00805   Healpix_Map<double> map (order,s1), map2 (order+2,s2), map3 (order, s1);
00806   for (int m=0; m<map.Npix(); ++m) map[m] = rng.rand_uni()+0.01;
00807   map2.Import(map);
00808   map3.Import(map2);
00809   for (int m=0; m<map.Npix(); ++m)
00810     if (!approx(map[m],map3[m],1e-12))
00811       FAIL(cout << "PROBLEM: order = " << order << endl)
00812   }
00813 void helper_udgrade2 (int nside)
00814   {
00815   Healpix_Map<double> map (nside,RING,SET_NSIDE), map2 (nside*3,RING,SET_NSIDE),
00816     map3 (nside, RING,SET_NSIDE);
00817   for (int m=0; m<map.Npix(); ++m) map[m] = rng.rand_uni()+0.01;
00818   map2.Import(map);
00819   map3.Import(map2);
00820   for (int m=0; m<map.Npix(); ++m)
00821     if (!approx(map[m],map3[m],1e-12))
00822       FAIL(cout << "PROBLEM: nside = " << nside << endl)
00823   }
00824 
00825 void check_import()
00826   {
00827   cout << "testing out-of-place swapping" << endl;
00828   for (int order=0; order<=7; ++order)
00829     helper_oop(order);
00830   cout << "testing downgrade(upgrade(map)) == map" << endl;
00831   for (int order=0; order<=7; ++order)
00832     {
00833     helper_udgrade(order,RING,RING);
00834     helper_udgrade(order,RING,NEST);
00835     helper_udgrade(order,NEST,NEST);
00836     helper_udgrade(order,NEST,RING);
00837     }
00838   for (int nside=3; nside<500; nside+=nside/2+1)
00839     helper_udgrade2(nside);
00840   }
00841 
00842 void check_average()
00843   {
00844   cout << "testing whether average(map) == average(downgraded map)" << endl;
00845   for (int order=1; order<=10; ++order)
00846     {
00847     Healpix_Map<double> map (order,RING), map2(1,RING);
00848     for (int m=0; m<map.Npix(); ++m)
00849       map[m] = rng.rand_uni()+0.01;
00850     map2.Import(map);
00851     double avg=map.average(), avg2=map2.average();
00852     if (!approx(avg,avg2,1e-13))
00853       FAIL(cout << "PROBLEM: order = " << order << " " << avg/avg2-1 << endl)
00854     }
00855   for (int nside=3; nside<1000; nside += nside/2+1)
00856     {
00857     Healpix_Map<double> map (nside,RING,SET_NSIDE), map2(1,RING,SET_NSIDE);
00858     for (int m=0; m<map.Npix(); ++m)
00859       map[m] = rng.rand_uni()+0.01;
00860     map2.Import(map);
00861     double avg=map.average(), avg2=map2.average();
00862     if (!approx(avg,avg2,1e-13))
00863       FAIL(cout << "PROBLEM: nside = " << nside << " " << avg/avg2-1 << endl)
00864     }
00865   }
00866 
00867 void random_alm (Alm<xcomplex<double> >&almT, Alm<xcomplex<double> >&almG,
00868   Alm<xcomplex<double> >&almC, int lmax, int mmax)
00869   {
00870   almT.Set(lmax,mmax); almG.Set(lmax,mmax); almC.Set(lmax,mmax);
00871 
00872   for (int l=0; l<=lmax; ++l)
00873     {
00874     almT(l,0)=dcomplex(rng.rand_gauss(),0.);
00875     almG(l,0)=dcomplex(rng.rand_gauss(),0.);
00876     almC(l,0)=dcomplex(rng.rand_gauss(),0.);
00877     }
00878 
00879   for (int m=1; m<=mmax; ++m)
00880     for (int l=m; l<=lmax; ++l)
00881       {
00882       almT(l,m).real(rng.rand_gauss()); almT(l,m).imag(rng.rand_gauss());
00883       almG(l,m).real(rng.rand_gauss()); almG(l,m).imag(rng.rand_gauss());
00884       almC(l,m).real(rng.rand_gauss()); almC(l,m).imag(rng.rand_gauss());
00885       }
00886   almG(0,0)=almC(0,0)=almG(1,0)=almC(1,0)=almG(1,1)=almC(1,1)=0;
00887   }
00888 
00889 void random_alm (Alm<xcomplex<double> >&alm, int lmax, int mmax)
00890   {
00891   alm.Set(lmax,mmax);
00892 
00893   for (int l=0; l<=lmax; ++l)
00894     { alm(l,0)=dcomplex(rng.rand_gauss(),0.); }
00895 
00896   for (int m=1; m<=mmax; ++m)
00897     for (int l=m; l<=lmax; ++l)
00898       { alm(l,m).real(rng.rand_gauss()); alm(l,m).imag(rng.rand_gauss()); }
00899   }
00900 
00901 void check_alm (const Alm<xcomplex<double> >&oalm,
00902   const Alm<xcomplex<double> >&alm, double epsilon)
00903   {
00904   for (int m=0; m<=alm.Mmax(); ++m)
00905     for (int l=m; l<=alm.Lmax(); ++l)
00906       {
00907       if (!abs_approx(oalm(l,m).real(),alm(l,m).real(),epsilon))
00908         FAIL(cout << "Problemr " << l << " " << m << endl)
00909       if (!abs_approx(oalm(l,m).imag(),alm(l,m).imag(),epsilon))
00910         FAIL(cout << "Problemi " << l << " " << m <<  endl)
00911       }
00912   }
00913 
00914 void check_alm2map2alm (int lmax, int mmax, int nside)
00915   {
00916   cout << "testing whether a_lm->map->a_lm returns original a_lm" << endl;
00917   cout << "lmax=" << lmax <<", mmax=" << mmax << ", nside=" << nside << endl;
00918   const double epsilon = 1e-8;
00919   Alm<xcomplex<double> > oalmT(lmax,mmax),almT(lmax,mmax),
00920     oalmG(lmax,mmax),almG(lmax,mmax),oalmC(lmax,mmax),almC(lmax,mmax);
00921   Healpix_Map<double> mapT(nside,RING,SET_NSIDE), mapQ(nside,RING,SET_NSIDE),
00922     mapU(nside,RING,SET_NSIDE);
00923 
00924   random_alm(oalmT,oalmG,oalmC,lmax,mmax);
00925   alm2map(oalmT,mapT);
00926   map2alm_iter2(mapT,almT,1e-12,1e-12);
00927   check_alm (oalmT, almT, epsilon);
00928 
00929   alm2map_spin(oalmG,oalmC,mapQ,mapU,1);
00930   map2alm_spin_iter2(mapQ,mapU,almG,almC,1,1e-12,1e-12);
00931   check_alm (oalmG, almG, epsilon);
00932   check_alm (oalmC, almC, epsilon);
00933 
00934   alm2map_pol(oalmT,oalmG,oalmC,mapT,mapQ,mapU);
00935   map2alm_pol_iter2(mapT,mapQ,mapU,almT,almG,almC,1e-12,1e-12);
00936   check_alm (oalmT, almT, epsilon);
00937   check_alm (oalmG, almG, epsilon);
00938   check_alm (oalmC, almC, epsilon);
00939   }
00940 
00941 void check_smooth_alm ()
00942   {
00943   cout << "testing whether unsmooth(smooth(a_lm)) returns a_lm" << endl;
00944   const double epsilon = 1e-14;
00945   const double fwhm = 100.*arcmin2rad;
00946   const int lmax=300, mmax=300;
00947   Alm<xcomplex<double> > oalmT(lmax,mmax),almT(lmax,mmax),
00948     oalmG(lmax,mmax),almG(lmax,mmax),oalmC(lmax,mmax),almC(lmax,mmax);
00949 
00950   random_alm(oalmT,oalmG,oalmC,lmax,mmax);
00951 
00952   almT=oalmT; almG=oalmG; almC=oalmC;
00953   smoothWithGauss (almT, fwhm);
00954   smoothWithGauss (almT, -fwhm);
00955   check_alm (oalmT, almT, epsilon);
00956   almT=oalmT;
00957   smoothWithGauss (almT, almG, almC, fwhm);
00958   smoothWithGauss (almT, almG, almC, -fwhm);
00959   check_alm (oalmT, almT, epsilon);
00960   check_alm (oalmG, almG, epsilon);
00961   check_alm (oalmC, almC, epsilon);
00962   }
00963 
00964 void check_rot_alm ()
00965   {
00966   cout << "testing whether rot^-1(rot(a_lm)) returns a_lm" << endl;
00967   const double epsilon = 2e-13;
00968   const int lmax=300;
00969   Alm<xcomplex<double> > oalm(lmax,lmax),alm(lmax,lmax);
00970 
00971   random_alm(oalm,lmax,lmax);
00972 
00973   alm=oalm;
00974   rotate_alm (alm,3,4,5);
00975   rotate_alm (alm,-5,-4,-3);
00976   check_alm (oalm, alm, epsilon);
00977   }
00978 
00979 void check_isqrt()
00980   {
00981   cout << "testing whether isqrt() works reliably" << endl;
00982   uint64 val=uint64(0xF234)<<16, valsq=val*val;
00983   if (isqrt(valsq)!=val) FAIL(cout << "PROBLEM1" << endl)
00984   if (isqrt(valsq-1)!=val-1) FAIL(cout << "PROBLEM2" << endl)
00985   }
00986 
00987 void check_pix2ang_acc()
00988   {
00989   cout << "testing accuracy of pix2ang at the poles" << endl;
00990   for (int m=0; m<=29;++m)
00991     {
00992     Healpix_Base2 base(m,RING);
00993     if (base.pix2ang(1).theta==0.)
00994       FAIL(cout << "PROBLEM: order " << m << endl)
00995     }
00996   }
00997 
00998 const int nsteps=1000000;
00999 
01000 template<typename I>void perf_neighbors(const string &name,
01001   Healpix_Ordering_Scheme scheme)
01002   {
01003   tsize cnt=0;
01004   wallTimers.start(name);
01005   int omax=T_Healpix_Base<I>::order_max;
01006   for (int order=0; order<=omax; ++order)
01007     {
01008     T_Healpix_Base<I> base (order,scheme);
01009     I dpix=max(base.Npix()/nsteps,I(1));
01010     fix_arr<I,8> nres;
01011     for (I pix=0; pix<base.Npix(); pix+=dpix)
01012       {
01013       base.neighbors(pix,nres);
01014       ++cnt;
01015       }
01016     }
01017   wallTimers.stop(name);
01018   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01019   }
01020 template<typename I>void perf_pix2ang(const string &name,
01021   Healpix_Ordering_Scheme scheme, double &dummy)
01022   {
01023   tsize cnt=0;
01024   wallTimers.start(name);
01025   int omax=T_Healpix_Base<I>::order_max;
01026   for (int order=0; order<=omax; ++order)
01027     {
01028     T_Healpix_Base<I> base (order,scheme);
01029     I dpix=max(base.Npix()/nsteps,I(1));
01030     for (I pix=0; pix<base.Npix(); pix+=dpix)
01031       {
01032       pointing p(base.pix2ang(pix));
01033       dummy+=p.theta+p.phi;
01034       ++cnt;
01035       }
01036     }
01037   wallTimers.stop(name);
01038   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01039   }
01040 template<typename I>void perf_pix2vec(const string &name,
01041   Healpix_Ordering_Scheme scheme, double &dummy)
01042   {
01043   tsize cnt=0;
01044   wallTimers.start(name);
01045   int omax=T_Healpix_Base<I>::order_max;
01046   for (int order=0; order<=omax; ++order)
01047     {
01048     T_Healpix_Base<I> base (order,scheme);
01049     I dpix=max(base.Npix()/nsteps,I(1));
01050     for (I pix=0; pix<base.Npix(); pix+=dpix)
01051       {
01052       vec3 v(base.pix2vec(pix));
01053       dummy+=v.x+v.y+v.z;
01054       ++cnt;
01055       }
01056     }
01057   wallTimers.stop(name);
01058   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01059   }
01060 template<typename I>void perf_pix2zphi(const string &name,
01061   Healpix_Ordering_Scheme scheme, double &dummy)
01062   {
01063   tsize cnt=0;
01064   wallTimers.start(name);
01065   int omax=T_Healpix_Base<I>::order_max;
01066   for (int order=0; order<=omax; ++order)
01067     {
01068     T_Healpix_Base<I> base (order,scheme);
01069     I dpix=max(base.Npix()/nsteps,I(1));
01070     double z,phi;
01071     for (I pix=0; pix<base.Npix(); pix+=dpix)
01072       {
01073       base.pix2zphi(pix,z,phi);
01074       dummy+=z+phi;
01075       ++cnt;
01076       }
01077     }
01078   wallTimers.stop(name);
01079   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01080   }
01081 template<typename I>void perf_zphi2pix(const string &name,
01082   Healpix_Ordering_Scheme scheme, double &dummy)
01083   {
01084   tsize cnt=0;
01085   wallTimers.start(name);
01086   int omax=T_Healpix_Base<I>::order_max;
01087   double dz=2./sqrt(nsteps);
01088   double dph=twopi/sqrt(nsteps);
01089   for (int order=0; order<=omax; ++order)
01090     {
01091     T_Healpix_Base<I> base (order,scheme);
01092     for (double z=-1; z<1; z+=dz)
01093       for (double phi=0; phi<twopi; phi+=dph)
01094         {
01095         dummy+=base.zphi2pix(z,phi);
01096         ++cnt;
01097         }
01098     }
01099   wallTimers.stop(name);
01100   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01101   }
01102 template<typename I>void perf_ang2pix(const string &name,
01103   Healpix_Ordering_Scheme scheme, double &dummy)
01104   {
01105   tsize cnt=0;
01106   wallTimers.start(name);
01107   int omax=T_Healpix_Base<I>::order_max;
01108   double dth=pi/sqrt(nsteps);
01109   double dph=twopi/sqrt(nsteps);
01110   for (int order=0; order<=omax; ++order)
01111     {
01112     T_Healpix_Base<I> base (order,scheme);
01113     for (double theta=0; theta<pi; theta+=dth)
01114       for (double phi=0; phi<twopi; phi+=dph)
01115         {
01116         dummy+=base.ang2pix(pointing(theta+1e-15*phi,phi));
01117         ++cnt;
01118         }
01119     }
01120   wallTimers.stop(name);
01121   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01122   }
01123 template<typename I>void perf_ring2nest(const string &name,double &dummy)
01124   {
01125   tsize cnt=0;
01126   wallTimers.start(name);
01127   int omax=T_Healpix_Base<I>::order_max;
01128   for (int order=0; order<=omax; ++order)
01129     {
01130     T_Healpix_Base<I> base (order,RING);
01131     I dpix=max(base.Npix()/nsteps,I(1));
01132     for (I pix=0; pix<base.Npix(); pix+=dpix)
01133       {
01134       dummy+=base.ring2nest(pix);
01135       ++cnt;
01136       }
01137     }
01138   wallTimers.stop(name);
01139   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01140   }
01141 template<typename I>void perf_nest2ring(const string &name,double &dummy)
01142   {
01143   tsize cnt=0;
01144   wallTimers.start(name);
01145   int omax=T_Healpix_Base<I>::order_max;
01146   for (int order=0; order<=omax; ++order)
01147     {
01148     T_Healpix_Base<I> base (order,RING);
01149     I dpix=max(base.Npix()/nsteps,I(1));
01150     for (I pix=0; pix<base.Npix(); pix+=dpix)
01151       {
01152       dummy+=base.nest2ring(pix);
01153       ++cnt;
01154       }
01155     }
01156   wallTimers.stop(name);
01157   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01158   }
01159 template<typename I>void perf_peano2nest(const string &name,double &dummy)
01160   {
01161   tsize cnt=0;
01162   wallTimers.start(name);
01163   int omax=T_Healpix_Base<I>::order_max;
01164   for (int order=0; order<=omax; ++order)
01165     {
01166     T_Healpix_Base<I> base (order,NEST);
01167     I dpix=max(base.Npix()/nsteps,I(1));
01168     for (I pix=0; pix<base.Npix(); pix+=dpix)
01169       {
01170       dummy+=base.peano2nest(pix);
01171       ++cnt;
01172       }
01173     }
01174   wallTimers.stop(name);
01175   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01176   }
01177 template<typename I>void perf_nest2peano(const string &name,double &dummy)
01178   {
01179   tsize cnt=0;
01180   wallTimers.start(name);
01181   int omax=T_Healpix_Base<I>::order_max;
01182   for (int order=0; order<=omax; ++order)
01183     {
01184     T_Healpix_Base<I> base (order,NEST);
01185     I dpix=max(base.Npix()/nsteps,I(1));
01186     for (I pix=0; pix<base.Npix(); pix+=dpix)
01187       {
01188       dummy+=base.nest2peano(pix);
01189       ++cnt;
01190       }
01191     }
01192   wallTimers.stop(name);
01193   cout << name << ": " << cnt/wallTimers.acc(name)*1e-6 << "MOps/s" << endl;
01194   }
01195 template<typename I>void perf_query_disc(const string &name,
01196   Healpix_Ordering_Scheme scheme, double &dummy)
01197   {
01198   tsize cnt=0;
01199   T_Healpix_Base<I> base(1024,scheme,SET_NSIDE);
01200   wallTimers.start(name);
01201   for (int m=0; m<1000; ++m)
01202     {
01203     rangeset<I> pix;
01204     base.query_disc(vec3(1,0,0),halfpi/9,pix);
01205     dummy+=pix.nranges();
01206     ++cnt;
01207     }
01208   wallTimers.stop(name);
01209   cout << name << ": " << cnt/wallTimers.acc(name)*1e-3 << "kOps/s" << endl;
01210   }
01211 template<typename I>void perf_query_triangle(const string &name,
01212   Healpix_Ordering_Scheme scheme, double &dummy)
01213   {
01214   tsize cnt=0;
01215   T_Healpix_Base<I> base(1024,scheme,SET_NSIDE);
01216   vector<pointing> corner;
01217   corner.push_back(vec3(1,0.01,0.01));
01218   corner.push_back(vec3(0.01,1,0.01));
01219   corner.push_back(vec3(0.01,0.01,1));
01220   wallTimers.start(name);
01221   for (int m=0; m<1000; ++m)
01222     {
01223     rangeset<I> pix;
01224     base.query_polygon(corner,pix);
01225     dummy+=pix.nranges();
01226     ++cnt;
01227     }
01228   wallTimers.stop(name);
01229   cout << name << ": " << cnt/wallTimers.acc(name)*1e-3 << "kOps/s" << endl;
01230   }
01231 template<typename I>void perf_query_polygon(const string &name,
01232   Healpix_Ordering_Scheme scheme, double &dummy)
01233   {
01234   tsize cnt=0;
01235   T_Healpix_Base<I> base(1024,scheme,SET_NSIDE);
01236   vector<pointing> corner;
01237   corner.push_back(vec3(1,0.01,0.01));
01238   corner.push_back(vec3(1,1,-0.3));
01239   corner.push_back(vec3(0.01,1,0.01));
01240   corner.push_back(vec3(0.01,0.01,1));
01241   wallTimers.start(name);
01242   for (int m=0; m<1000; ++m)
01243     {
01244     rangeset<I> pix;
01245     base.query_polygon(corner,pix);
01246     dummy+=pix.nranges();
01247     ++cnt;
01248     }
01249   wallTimers.stop(name);
01250   cout << name << ": " << cnt/wallTimers.acc(name)*1e-3 << "kOps/s" << endl;
01251   }
01252 
01253 void perftest()
01254   {
01255   double dummy=0;
01256   cout << "Measuring performance of Healpix_Base methods." << endl;
01257   perf_pix2zphi<int>   ("pix2zphi (RING):int  ",RING,dummy);
01258   perf_pix2zphi<int>   ("pix2zphi (NEST):int  ",NEST,dummy);
01259   perf_pix2zphi<int64> ("pix2zphi (RING):int64",RING,dummy);
01260   perf_pix2zphi<int64> ("pix2zphi (NEST):int64",NEST,dummy);
01261   perf_zphi2pix<int>   ("zphi2pix (RING):int  ",RING,dummy);
01262   perf_zphi2pix<int>   ("zphi2pix (NEST):int  ",NEST,dummy);
01263   perf_zphi2pix<int64> ("zphi2pix (RING):int64",RING,dummy);
01264   perf_zphi2pix<int64> ("zphi2pix (NEST):int64",NEST,dummy);
01265   perf_pix2ang<int>    ("pix2ang  (RING):int  ",RING,dummy);
01266   perf_pix2ang<int>    ("pix2ang  (NEST):int  ",NEST,dummy);
01267   perf_pix2ang<int64>  ("pix2ang  (RING):int64",RING,dummy);
01268   perf_pix2ang<int64>  ("pix2ang  (NEST):int64",NEST,dummy);
01269   perf_ang2pix<int>    ("ang2pix  (RING):int  ",RING,dummy);
01270   perf_ang2pix<int>    ("ang2pix  (NEST):int  ",NEST,dummy);
01271   perf_ang2pix<int64>  ("ang2pix  (RING):int64",RING,dummy);
01272   perf_ang2pix<int64>  ("ang2pix  (NEST):int64",NEST,dummy);
01273   perf_pix2vec<int>    ("pix2vec  (RING):int  ",RING,dummy);
01274   perf_pix2vec<int>    ("pix2vec  (NEST):int  ",NEST,dummy);
01275   perf_pix2vec<int64>  ("pix2vec  (RING):int64",RING,dummy);
01276   perf_pix2vec<int64>  ("pix2vec  (NEST):int64",NEST,dummy);
01277   perf_neighbors<int>  ("neighbors(NEST):int  ",NEST);
01278   perf_neighbors<int>  ("neighbors(RING):int  ",RING);
01279   perf_neighbors<int64>("neighbors(NEST):int64",NEST);
01280   perf_neighbors<int64>("neighbors(RING):int64",RING);
01281   perf_ring2nest<int>  ("ring2nest      :int  ",dummy);
01282   perf_ring2nest<int64>("ring2nest      :int64",dummy);
01283   perf_nest2ring<int>  ("nest2ring      :int  ",dummy);
01284   perf_nest2ring<int64>("nest2ring      :int64",dummy);
01285   perf_peano2nest<int>  ("peano2nest     :int  ",dummy);
01286   perf_peano2nest<int64>("peano2nest     :int64",dummy);
01287   perf_nest2peano<int>  ("nest2peano     :int  ",dummy);
01288   perf_nest2peano<int64>("nest2peano     :int64",dummy);
01289   perf_query_disc<int>      ("query_disc    (RING):int  ",RING,dummy);
01290   perf_query_disc<int>      ("query_disc    (NEST):int  ",NEST,dummy);
01291   perf_query_disc<int64>    ("query_disc    (RING):int64",RING,dummy);
01292   perf_query_disc<int64>    ("query_disc    (NEST):int64",NEST,dummy);
01293   perf_query_triangle<int>  ("query_triangle(RING):int  ",RING,dummy);
01294   perf_query_triangle<int>  ("query_triangle(NEST):int  ",NEST,dummy);
01295   perf_query_triangle<int64>("query_triangle(RING):int64",RING,dummy);
01296   perf_query_triangle<int64>("query_triangle(NEST):int64",NEST,dummy);
01297   perf_query_polygon<int>   ("query_polygon (RING):int  ",RING,dummy);
01298   perf_query_polygon<int>   ("query_polygon (NEST):int  ",NEST,dummy);
01299   perf_query_polygon<int64> ("query_polygon (RING):int64",RING,dummy);
01300   perf_query_polygon<int64> ("query_polygon (NEST):int64",NEST,dummy);
01301 
01302   if (dummy<0) cout << dummy << endl;
01303   }
01304 
01305 } // unnamed namespace
01306 
01307 int main(int argc, const char **argv)
01308   {
01309   module_startup ("hpxtest",argc,argv,1,"");
01310   perftest();
01311   check_compress<int>();
01312   check_compress<unsigned>();
01313   check_compress<int64>();
01314   check_compress<uint64>();
01315   check_Moc<int>();
01316   check_Moc<int64>();
01317   check_rangeset<int>();
01318   check_rangeset<int64>();
01319   check_isqrt();
01320   check_pix2ang_acc();
01321   check_smooth_alm();
01322   check_rot_alm();
01323   check_alm2map2alm(620,620,256);
01324   check_alm2map2alm(620,2,256);
01325   check_average();
01326   check_import();
01327   check_ringnestring<int>();
01328   check_ringnestring<int64>();
01329   check_nestpeanonest<int>();
01330   check_nestpeanonest<int64>();
01331   check_pixzphipix<int>();
01332   check_pixzphipix<int64>();
01333   check_zphipixzphi<int>();
01334   check_zphipixzphi<int64>();
01335   check_pixangpix<int>();
01336   check_pixangpix<int64>();
01337   check_neighbors<int>();
01338   check_neighbors<int64>();
01339   check_swap_scheme();
01340   check_query_disc_strict(RING);
01341   check_query_disc_strict(NEST);
01342   check_issue_229(RING);
01343   check_issue_229(NEST);
01344   check_query_disc<int>();
01345   check_query_disc<int64>();
01346   check_query_polygon<int>();
01347   check_query_polygon<int64>();
01348 #ifdef UNITTESTS
01349   if (errcount>0) planck_fail("unit test errors");
01350 #endif
01351   }

Generated on Thu Oct 8 14:48:52 2015 for Healpix C++