33 #include "geom_utils.h" 34 #include "lsconstants.h" 40 planck_assert (nside>I(0),
"invalid value for Nside");
41 return ((nside)&(nside-1)) ? -1 : ilog2(nside);
45 I res=isqrt(npix/I(12));
46 planck_assert (npix==res*res*I(12),
"invalid value for npix");
54 return I(nside_*(2-1.5*z));
55 I iring = I(nside_*sqrt(3*(1-az)));
56 return (z>0) ? iring : 4*nside_-iring-1;
67 template<
typename I,
typename I2>
inline void check_pixel (
int o,
int order_,
68 int omax,
int zone, rangeset<I2> &pixset, I pix, vector<pair<I,int> > &stk,
69 bool inclusive,
int &stacktop)
77 int sdist=2*(order_-o);
78 pixset.append(pix<<sdist,(pix+1)<<sdist);
81 for (
int i=0; i<4; ++i)
82 stk.push_back(make_pair(4*pix+3-i,o+1));
88 pixset.append(pix>>(2*(o-order_)));
94 for (
int i=0; i<4; ++i)
95 stk.push_back(make_pair(4*pix+3-i,o+1));
98 pixset.append(pix>>(2*(o-order_)));
112 for (
int i=0; i<4; ++i)
113 stk.push_back(make_pair(4*pix+3-i,o+1));
123 double cz,
double cphi,
double cosrp2, I cpix)
125 if (pix>=nr) pix-=nr;
128 if (pix==cpix)
return false;
130 b1.pix2xyf(pix,px,py,pf);
131 for (
int i=0; i<fct-1; ++i)
133 I ox=fct*px, oy=fct*py;
135 b2.
pix2zphi(b2.xyf2pix(ox+i,oy,pf),pz,pphi);
136 if (cosdist_zphi(pz,pphi,cz,cphi)>cosrp2)
138 b2.
pix2zphi(b2.xyf2pix(ox+fct-1,oy+i,pf),pz,pphi);
139 if (cosdist_zphi(pz,pphi,cz,cphi)>cosrp2)
141 b2.
pix2zphi(b2.xyf2pix(ox+fct-1-i,oy+fct-1,pf),pz,pphi);
142 if (cosdist_zphi(pz,pphi,cz,cphi)>cosrp2)
144 b2.
pix2zphi(b2.xyf2pix(ox,oy+fct-1-i,pf),pz,pphi);
145 if (cosdist_zphi(pz,pphi,cz,cphi)>cosrp2)
153 template<
typename I>
template<
typename I2>
155 (pointing ptg,
double radius,
int fact, rangeset<I2> &pixset)
const 157 bool inclusive = (fact!=0);
166 planck_assert (((I(1)<<order_max)/nside_)>=fact,
167 "invalid oversampling factor");
176 rbig = radius+max_pixrad();
179 rsmall = rbig = inclusive ? radius+max_pixrad() : radius;
182 { pixset.append(0,npix_);
return; }
186 double cosrsmall = cos(rsmall);
187 double cosrbig = cos(rbig);
189 double z0 = cos(ptg.theta);
190 double xa = 1./sqrt((1-z0)*(1+z0));
192 I cpix=zphi2pix(z0,ptg.phi);
194 double rlat1 = ptg.theta - rsmall;
195 double zmax = cos(rlat1);
196 I irmin = ring_above (zmax)+1;
198 if ((rlat1<=0) && (irmin>1))
201 get_ring_info_small(irmin-1,sp,rp,dummy);
202 pixset.append(0,sp+rp);
205 if ((fct>1) && (rlat1>0)) irmin=max(I(1),irmin-1);
207 double rlat2 = ptg.theta + rsmall;
208 double zmin = cos(rlat2);
209 I irmax = ring_above (zmin);
211 if ((fct>1) && (rlat2<pi)) irmax=min(4*nside_-1,irmax+1);
213 for (I iz=irmin; iz<=irmax; ++iz)
216 double x = (cosrbig-z*z0)*xa;
217 double ysq = 1-z*z-x*x;
219 bool fullcircle =
false;
231 dphi = atan2(sqrt(ysq),x);
236 get_ring_info_small(iz,ipix1,nr,shifted);
237 double shift = shifted ? 0.5 : 0.;
239 I ipix2 = ipix1 + nr - 1;
241 I ip_lo = ifloor<I>(nr*inv_twopi*(ptg.phi-dphi) - shift)+1;
242 I ip_hi = ifloor<I>(nr*inv_twopi*(ptg.phi+dphi) - shift);
245 if (ip_hi-ip_lo<nr-1)
256 while ((ip_lo<=ip_hi) && check_pixel_ring
257 (*
this,b2,ip_lo,nr,ipix1,fct,z0,ptg.phi,cosrsmall,cpix))
259 while ((ip_hi>ip_lo) && check_pixel_ring
260 (*
this,b2,ip_hi,nr,ipix1,fct,z0,ptg.phi,cosrsmall,cpix))
267 { ip_lo-=nr; ip_hi-=nr; }
270 pixset.append(ipix1,ipix1+ip_hi+1);
271 pixset.append(ipix1+ip_lo+nr,ipix2+1);
274 pixset.append(ipix1+ip_lo,ipix1+ip_hi+1);
278 if ((rlat2>=pi) && (irmax+1<4*nside_))
281 get_ring_info_small(irmax+1,sp,rp,dummy);
282 pixset.append(sp,npix_);
288 { pixset.append(0,npix_);
return; }
293 planck_assert ((I(1)<<(order_max-order_))>=fact,
294 "invalid oversampling factor");
295 planck_assert ((fact&(fact-1))==0,
296 "oversampling factor must be a power of 2");
299 int omax=order_+oplus;
302 arr<T_Healpix_Base<I> > base(omax+1);
303 arr<double> crpdr(omax+1), crmdr(omax+1);
304 double cosrad=cos(radius);
305 for (
int o=0; o<=omax; ++o)
308 double dr=base[o].max_pixrad();
309 crpdr[o] = (radius+dr>pi) ? -1. : cos(radius+dr);
310 crmdr[o] = (radius-dr<0.) ? 1. : cos(radius-dr);
312 vector<pair<I,int> > stk;
313 stk.reserve(12+3*omax);
314 for (
int i=0; i<12; ++i)
315 stk.push_back(make_pair(I(11-i),0));
322 I pix=stk.back().first;
323 int o=stk.back().second;
327 base[o].pix2zphi(pix,z,phi);
329 double cangdist=cosdist_zphi(vptg.z,ptg.phi,z,phi);
331 if (cangdist>crpdr[o])
333 int zone = (cangdist<cosrad) ? 1 : ((cangdist<=crmdr[o]) ? 2 : 3);
335 check_pixel (o, order_, omax, zone, pixset, pix, stk, inclusive,
343 (pointing ptg,
double radius, rangeset<I> &pixset)
const 345 query_disc_internal (ptg, radius, 0, pixset);
349 (pointing ptg,
double radius, rangeset<I> &pixset,
int fact)
const 351 planck_assert(fact>0,
"fact must be a positive integer");
352 if ((
sizeof(I)<8) && (((I(1)<<order_max)/nside_)<fact))
355 base2.query_disc_internal(ptg,radius,fact,pixset);
358 query_disc_internal (ptg, radius, fact, pixset);
361 template<
typename I>
template<
typename I2>
363 const arr<double> &rad,
int fact, rangeset<I2> &pixset)
const 365 bool inclusive = (fact!=0);
366 tsize nv=norm.size();
367 planck_assert(nv==rad.size(),
"inconsistent input arrays");
375 planck_assert (((I(1)<<order_max)/nside_)>=fact,
376 "invalid oversampling factor");
380 double rpsmall, rpbig;
385 rpbig = max_pixrad();
388 rpsmall = rpbig = inclusive ? max_pixrad() : 0;
390 I irmin=1, irmax=4*nside_-1;
391 vector<double> z0,xa,cosrsmall,cosrbig;
392 vector<pointing> ptg;
394 for (tsize i=0; i<nv; ++i)
396 double rsmall=rad[i]+rpsmall;
399 double rbig=min(pi,rad[i]+rpbig);
400 pointing pnt=pointing(norm[i]);
401 cosrsmall.push_back(cos(rsmall));
402 cosrbig.push_back(cos(rbig));
403 double cth=cos(pnt.theta);
405 if (fct>1) cpix.push_back(zphi2pix(cth,pnt.phi));
406 xa.push_back(1./sqrt((1-cth)*(1+cth)));
409 double rlat1 = pnt.theta - rsmall;
410 double zmax = cos(rlat1);
411 I irmin_t = (rlat1<=0) ? 1 : ring_above (zmax)+1;
413 if ((fct>1) && (rlat1>0)) irmin_t=max(I(1),irmin_t-1);
415 double rlat2 = pnt.theta + rsmall;
416 double zmin = cos(rlat2);
417 I irmax_t = (rlat2>=pi) ? 4*nside_-1 : ring_above (zmin);
419 if ((fct>1) && (rlat2<pi)) irmax_t=min(4*nside_-1,irmax_t+1);
421 if (irmax_t < irmax) irmax=irmax_t;
422 if (irmin_t > irmin) irmin=irmin_t;
426 for (I iz=irmin; iz<=irmax; ++iz)
431 get_ring_info_small(iz,ipix1,nr,shifted);
432 double shift = shifted ? 0.5 : 0.;
434 tr.append(ipix1,ipix1+nr);
435 for (tsize j=0; j<z0.size(); ++j)
437 double x = (cosrbig[j]-z*z0[j])*xa[j];
438 double ysq = 1.-z*z-x*x;
441 double dphi = atan2(sqrt(ysq),x);
442 I ip_lo = ifloor<I>(nr*inv_twopi*(ptg[j].phi-dphi) - shift)+1;
443 I ip_hi = ifloor<I>(nr*inv_twopi*(ptg[j].phi+dphi) - shift);
446 while ((ip_lo<=ip_hi) && check_pixel_ring
447 (*
this,b2,ip_lo,nr,ipix1,fct,z0[j],ptg[j].phi,cosrsmall[j],cpix[j]))
449 while ((ip_hi>ip_lo) && check_pixel_ring
450 (*
this,b2,ip_hi,nr,ipix1,fct,z0[j],ptg[j].phi,cosrsmall[j],cpix[j]))
454 { ip_lo-=nr; ip_hi-=nr;}
456 tr.remove(ipix1+ip_hi+1,ipix1+ip_lo+nr);
458 tr.intersect(ipix1+ip_lo,ipix1+ip_hi+1);
469 planck_assert ((I(1)<<(order_max-order_))>=fact,
470 "invalid oversampling factor");
471 planck_assert ((fact&(fact-1))==0,
472 "oversampling factor must be a power of 2");
475 int omax=order_+oplus;
479 arr<T_Healpix_Base<I> > base(omax+1);
480 arr3<double> crlimit(omax+1,nv,3);
481 for (
int o=0; o<=omax; ++o)
484 double dr=base[o].max_pixrad();
485 for (tsize i=0; i<nv; ++i)
487 crlimit(o,i,0) = (rad[i]+dr>pi) ? -1. : cos(rad[i]+dr);
488 crlimit(o,i,1) = (o==0) ? cos(rad[i]) : crlimit(0,i,1);
489 crlimit(o,i,2) = (rad[i]-dr<0.) ? 1. : cos(rad[i]-dr);
493 vector<pair<I,int> > stk;
494 stk.reserve(12+3*omax);
495 for (
int i=0; i<12; ++i)
496 stk.push_back(make_pair(I(11-i),0));
503 I pix=stk.back().first;
504 int o=stk.back().second;
507 vec3 pv(base[o].pix2vec(pix));
510 for (tsize i=0; i<nv; ++i)
512 double crad=dotprod(pv,norm[i]);
513 for (tsize iz=0; iz<zone; ++iz)
514 if (crad<crlimit(o,i,iz))
515 if ((zone=iz)==0)
goto bailout;
518 check_pixel (o, order_, omax, zone, pixset, pix, stk, inclusive,
526 (
const arr<vec3> &norm,
const arr<double> &rad,
bool inclusive,
527 const vector<int> &cmds, rangeset<I> &pixset)
const 529 tsize nv=norm.size();
530 planck_assert(nv==rad.size(),
"inconsistent input arrays");
535 planck_fail (
"not yet implemented");
539 int oplus=inclusive ? 2 : 0;
540 int omax=min<int>(order_max,order_+oplus);
544 arr<T_Healpix_Base<I> > base(omax+1);
545 arr3<double> crlimit(omax+1,nv,3);
546 for (
int o=0; o<=omax; ++o)
549 double dr=base[o].max_pixrad();
550 for (tsize i=0; i<nv; ++i)
552 crlimit(o,i,0) = (rad[i]+dr>pi) ? -1. : cos(rad[i]+dr);
553 crlimit(o,i,1) = (o==0) ? cos(rad[i]) : crlimit(0,i,1);
554 crlimit(o,i,2) = (rad[i]-dr<0.) ? 1. : cos(rad[i]-dr);
558 vector<pair<I,int> > stk;
559 stk.reserve(12+3*omax);
560 for (
int i=0; i<12; ++i)
561 stk.push_back(make_pair(I(11-i),0));
566 vector<tsize> zstk; zstk.reserve(cmds.size());
571 I pix=stk.back().first;
572 int o=stk.back().second;
575 vec3 pv(base[o].pix2vec(pix));
577 for (tsize i=0; i<nv; ++i)
580 double crad=dotprod(pv,norm[i]);
581 for (tsize iz=0; iz<zone[i]; ++iz)
582 if (crad<crlimit(o,i,iz))
586 for (tsize i=0; i<cmds.size(); ++i)
592 tmp=zstk.back(); zstk.pop_back();
593 zstk.back() = max(zstk.back(),tmp);
596 tmp=zstk.back(); zstk.pop_back();
597 zstk.back() = min(zstk.back(),tmp);
600 zstk.push_back(zone[cmds[i]]);
603 planck_assert(zstk.size()==1,
"inconsistent commands");
604 tsize zn=zstk[0]; zstk.pop_back();
606 check_pixel (o, order_, omax, zn, pixset, pix, stk, inclusive,
615 {
return utab[v&0xff] | (utab[(v>>8)&0xff]<<16); }
618 return int64(utab[ v &0xff]) | (int64(utab[(v>> 8)&0xff])<<16)
619 | (int64(utab[(v>>16)&0xff])<<32) | (int64(utab[(v>>24)&0xff])<<48);
624 int raw = (v&0x5555) | ((v&0x55550000)>>15);
625 return ctab[raw&0xff] | (ctab[raw>>8]<<4);
629 int64 raw = v&0x5555555555555555ull;
631 return ctab[ raw &0xff] | (ctab[(raw>> 8)&0xff]<< 4)
632 | (ctab[(raw>>32)&0xff]<<16) | (ctab[(raw>>40)&0xff]<<20);
637 #include <x86intrin.h> 640 {
return _pdep_u32(v,0x55555555u); }
642 {
return _pdep_u64(v,0x5555555555555555ull); }
644 {
return _pext_u32(v,0x55555555u); }
646 {
return _pext_u64(v,0x5555555555555555ull); }
651 int &iy,
int &face_num)
const 653 face_num = pix>>(2*order_);
655 ix = compress_bits(pix);
656 iy = compress_bits(pix>>1);
661 {
return (I(face_num)<<(2*order_)) + spread_bits(ix) + (spread_bits(iy)<<1); }
666 template<
typename I>
inline I special_div(I a, I b)
670 return (t<<1)+(a>=b);
678 I iring, iphi, kshift, nr;
683 iring = (1+isqrt(1+2*pix))>>1;
684 iphi = (pix+1) - 2*iring*(iring-1);
687 face_num=special_div(iphi-1,nr);
689 else if (pix<(npix_-ncap_))
692 I tmp = (order_>=0) ? ip>>(order_+2) : ip/(4*nside_);
694 iphi = ip-tmp*4*nside_ + 1;
695 kshift = (iring+nside_)&1;
699 I ifm = iphi - (ire>>1) + nside_ -1,
700 ifp = iphi - (irm>>1) + nside_ -1;
702 { ifm >>= order_; ifp >>= order_; }
704 { ifm /= nside_; ifp /= nside_; }
705 face_num = (ifp==ifm) ? (ifp|4) : ((ifp<ifm) ? ifp : (ifm+8));
710 iring = (1+isqrt(2*ip-1))>>1;
711 iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
715 face_num=special_div(iphi-1,nr)+8;
718 I irt = iring - ((2+(face_num>>2))*nside_) + 1;
719 I ipt = 2*iphi- jpll[face_num]*nr - kshift -1;
721 if (ipt>=nl2) ipt-=8*nside_;
731 I jr = (jrll[face_num]*nside_) - ix - iy - 1;
733 I nr, kshift, n_before;
736 get_ring_info_small(jr,n_before,nr,shifted);
739 I jp = (jpll[face_num]*nr + ix - iy + 1 + kshift) / 2;
740 planck_assert(jp<=4*nr,
"must not happen");
743 return n_before + jp - 1;
747 : order_(-1), nside_(0), npface_(0), ncap_(0), npix_(0),
748 fact1_(0), fact2_(0), scheme_(
RING) {}
753 planck_assert ((order>=0)&&(order<=order_max),
"bad order");
755 nside_ = I(1)<<order;
756 npface_ = nside_<<order_;
757 ncap_ = (npface_-nside_)<<1;
760 fact1_ = (nside_<<1)*fact2_;
766 order_ = nside2order(nside);
767 planck_assert ((scheme!=
NEST) || (order_>=0),
768 "SetNside: nside must be power of 2 for nested maps");
770 npface_ = nside_*nside_;
771 ncap_ = (npface_-nside_)<<1;
774 fact1_ = (nside_<<1)*fact2_;
781 return 1 - ring*ring*fact2_;
783 return (2*nside_-ring)*fact1_;
784 ring=4*nside_ - ring;
785 return ring*ring*fact2_ - 1;
793 return (1+I(isqrt(1+2*pix)))>>1;
794 else if (pix<(npix_-ncap_))
795 return (pix-ncap_)/(4*nside_) + nside_;
797 return 4*nside_-((1+I(isqrt(2*(npix_-pix)-1)))>>1);
801 int face_num, ix, iy;
802 nest2xyf(pix,ix,iy,face_num);
803 return (I(jrll[face_num])<<order_) - ix - iy - 1;
809 planck_assert(order_>=0,
"hierarchical map required");
810 int ix, iy, face_num;
811 nest2xyf (pix, ix, iy, face_num);
812 return xyf2ring (ix, iy, face_num);
817 planck_assert(order_>=0,
"hierarchical map required");
818 int ix, iy, face_num;
819 ring2xyf (pix, ix, iy, face_num);
820 return xyf2nest (ix, iy, face_num);
824 (I pix,
int dir)
const 826 int face = (pix>>(2*order_));
828 int state = ((peano_face2path[dir][face]<<4))|(dir<<7);
829 int shift=2*order_-4;
830 for (; shift>=0; shift-=4)
832 state=peano_arr2[(state&0xF0) | ((pix>>shift)&0xF)];
833 result = (result<<4) | (state&0xF);
837 state=peano_arr[((state>>2)&0xFC) | (pix&0x3)];
838 result = (result<<2) | (state&0x3);
841 return result + (I(peano_face2face[dir][face])<<(2*order_));
845 {
return nest_peano_helper(pix,0); }
848 {
return nest_peano_helper(pix,1); }
851 double sth,
bool have_sth)
const 854 double tt = fmodulo(phi*inv_halfpi,4.0);
861 double temp1 = nside_*(0.5+tt);
862 double temp2 = nside_*z*0.75;
863 I jp = I(temp1-temp2);
864 I jm = I(temp1+temp2);
867 I ir = nside_ + 1 + jp - jm;
870 I t1 = jp+jm-nside_+kshift+1+nl4+nl4;
872 (t1>>1)&(nl4-1) : ((t1>>1)%nl4);
874 return ncap_ + (ir-1)*nl4 + ip;
878 double tp = tt-I(tt);
879 double tmp = ((za<0.99)||(!have_sth)) ?
880 nside_*sqrt(3*(1-za)) :
881 nside_*sth/sqrt((1.+za)/3.);
884 I jm = I((1.0-tp)*tmp);
888 planck_assert((ip>=0)&&(ip<4*ir),
"must not happen");
891 return (z>0) ? 2*ir*(ir-1) + ip : npix_ - 2*ir*(ir+1) + ip;
898 double temp1 = nside_*(0.5+tt);
899 double temp2 = nside_*(z*0.75);
900 I jp = I(temp1-temp2);
901 I jm = I(temp1+temp2);
902 I ifp = jp >> order_;
903 I ifm = jm >> order_;
904 int face_num = (ifp==ifm) ? (ifp|4) : ((ifp<ifm) ? ifp : (ifm+8));
906 int ix = jm & (nside_-1),
907 iy = nside_ - (jp & (nside_-1)) - 1;
908 return xyf2nest(ix,iy,face_num);
912 int ntt = min(3,
int(tt));
914 double tmp = ((za<0.99)||(!have_sth)) ?
915 nside_*sqrt(3*(1-za)) :
916 nside_*sth/sqrt((1.+za)/3.);
919 I jm = I((1.0-tp)*tmp);
923 xyf2nest(nside_-jm -1,nside_-jp-1,ntt) : xyf2nest(jp,jm,ntt+8);
929 double &phi,
double &sth,
bool &have_sth)
const 936 I iring = (1+I(isqrt(1+2*pix)))>>1;
937 I iphi = (pix+1) - 2*iring*(iring-1);
939 double tmp=(iring*iring)*fact2_;
941 if (z>0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=
true; }
942 phi = (iphi-0.5) * halfpi/iring;
944 else if (pix<(npix_-ncap_))
948 I tmp = (order_>=0) ? ip>>(order_+2) : ip/nl4;
949 I iring = tmp + nside_,
952 double fodd = ((iring+nside_)&1) ? 1 : 0.5;
954 z = (2*nside_-iring)*fact1_;
955 phi = (iphi-fodd) * pi*0.75*fact1_;
960 I iring = (1+I(isqrt(2*ip-1)))>>1;
961 I iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
963 double tmp=(iring*iring)*fact2_;
965 if (z<-0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=
true; }
966 phi = (iphi-0.5) * halfpi/iring;
971 int face_num, ix, iy;
972 nest2xyf(pix,ix,iy,face_num);
974 I jr = (I(jrll[face_num])<<order_) - ix - iy - 1;
980 double tmp=(nr*nr)*fact2_;
982 if (z>0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=
true; }
984 else if (jr > 3*nside_)
987 double tmp=(nr*nr)*fact2_;
989 if (z<-0.99) { sth=sqrt(tmp*(2.-tmp)); have_sth=
true; }
994 z = (2*nside_-jr)*fact1_;
997 I tmp=I(jpll[face_num])*nr+ix-iy;
998 planck_assert(tmp<8*nr,
"must not happen");
999 if (tmp<0) tmp+=8*nr;
1000 phi = (nr==nside_) ? 0.75*halfpi*tmp*fact1_ :
1001 (0.5*halfpi*tmp)/nr;
1005 template<
typename I>
template<
typename I2>
1007 (
const vector<pointing> &vertex,
int fact, rangeset<I2> &pixset)
const 1009 bool inclusive = (fact!=0);
1010 tsize nv=vertex.size();
1011 tsize ncirc = inclusive ? nv+1 : nv;
1012 planck_assert(nv>=3,
"not enough vertices in polygon");
1013 vector<vec3> vv(nv);
1014 for (tsize i=0; i<nv; ++i)
1015 vv[i]=vertex[i].to_vec3();
1016 arr<vec3> normal(ncirc);
1018 for (tsize i=0; i<nv; ++i)
1020 normal[i]=crossprod(vv[i],vv[(i+1)%nv]).Norm();
1021 double hnd=dotprod(normal[i],vv[(i+2)%nv]);
1022 planck_assert(abs(hnd)>1e-10,
"degenerate corner");
1024 flip = (hnd<0.) ? -1 : 1;
1026 planck_assert(flip*hnd>0,
"polygon is not convex");
1029 arr<double> rad(ncirc,halfpi);
1033 find_enclosing_circle (vv, normal[nv], cosrad);
1034 rad[nv]=acos(cosrad);
1036 query_multidisc(normal,rad,fact,pixset);
1040 (
const vector<pointing> &vertex, rangeset<I> &pixset)
const 1042 query_polygon_internal(vertex, 0, pixset);
1046 (
const vector<pointing> &vertex, rangeset<I> &pixset,
int fact)
const 1048 planck_assert(fact>0,
"fact must be a positive integer");
1049 if ((
sizeof(I)<8) && (((I(1)<<order_max)/nside_)<fact))
1052 base2.query_polygon_internal(vertex,fact,pixset);
1055 query_polygon_internal(vertex, fact, pixset);
1059 (
double theta1,
double theta2,
bool inclusive, rangeset<I> &pixset)
const 1063 I ring1 = max(I(1),1+ring_above(cos(theta1))),
1064 ring2 = min(4*nside_-1,ring_above(cos(theta2)));
1067 ring1 = max(I(1),ring1-1);
1068 ring2 = min(4*nside_-1,ring2+1);
1073 get_ring_info_small(ring1,sp1,rp1,dummy);
1074 get_ring_info_small(ring2,sp2,rp2,dummy);
1077 if (pix1<=pix2) pixset.append(pix1,pix2);
1080 planck_fail(
"query_strip not yet implemented for NESTED");
1084 double theta2,
bool inclusive, rangeset<I> &pixset)
const 1089 query_strip_internal(theta1,theta2,inclusive,pixset);
1092 query_strip_internal(0.,theta2,inclusive,pixset);
1094 query_strip_internal(theta1,pi,inclusive,ps2);
1100 (I ring, I &startpix, I &ringpix,
bool &shifted)
const 1106 startpix = 2*ring*(ring-1);
1108 else if (ring < 3*nside_)
1110 shifted = ((ring-nside_) & 1) == 0;
1112 startpix = ncap_ + (ring-nside_)*ringpix;
1117 I nr= 4*nside_-ring;
1119 startpix = npix_-2*nr*(nr+1);
1124 I &ringpix,
double &costheta,
double &sintheta,
bool &shifted)
const 1126 I northring = (ring>2*nside_) ? 4*nside_-ring : ring;
1127 if (northring < nside_)
1129 double tmp = northring*northring*fact2_;
1131 sintheta = sqrt(tmp*(2-tmp));
1132 ringpix = 4*northring;
1134 startpix = 2*northring*(northring-1);
1138 costheta = (2*nside_-northring)*fact1_;
1139 sintheta = sqrt((1+costheta)*(1-costheta));
1141 shifted = ((northring-nside_) & 1) == 0;
1142 startpix = ncap_ + (northring-nside_)*ringpix;
1144 if (northring != ring)
1146 costheta = -costheta;
1147 startpix = npix_ - startpix - ringpix;
1151 I &startpix, I &ringpix,
double &theta,
bool &shifted)
const 1153 I northring = (ring>2*nside_) ? 4*nside_-ring : ring;
1154 if (northring < nside_)
1156 double tmp = northring*northring*fact2_;
1157 double costheta = 1 - tmp;
1158 double sintheta = sqrt(tmp*(2-tmp));
1159 theta = atan2(sintheta,costheta);
1160 ringpix = 4*northring;
1162 startpix = 2*northring*(northring-1);
1166 theta = acos((2*nside_-northring)*fact1_);
1168 shifted = ((northring-nside_) & 1) == 0;
1169 startpix = ncap_ + (northring-nside_)*ringpix;
1171 if (northring != ring)
1174 startpix = npix_ - startpix - ringpix;
1179 fix_arr<I,8> &result)
const 1181 int ix, iy, face_num;
1183 ring2xyf(pix,ix,iy,face_num) : nest2xyf(pix,ix,iy,face_num);
1185 const I nsm1 = nside_-1;
1186 if ((ix>0)&&(ix<nsm1)&&(iy>0)&&(iy<nsm1))
1189 for (
int m=0; m<8; ++m)
1190 result[m] = xyf2ring(ix+nb_xoffset[m],iy+nb_yoffset[m],face_num);
1193 I fpix = I(face_num)<<(2*order_),
1194 px0=spread_bits(ix ), py0=spread_bits(iy )<<1,
1195 pxp=spread_bits(ix+1), pyp=spread_bits(iy+1)<<1,
1196 pxm=spread_bits(ix-1), pym=spread_bits(iy-1)<<1;
1198 result[0] = fpix+pxm+py0; result[1] = fpix+pxm+pyp;
1199 result[2] = fpix+px0+pyp; result[3] = fpix+pxp+pyp;
1200 result[4] = fpix+pxp+py0; result[5] = fpix+pxp+pym;
1201 result[6] = fpix+px0+pym; result[7] = fpix+pxm+pym;
1206 for (
int i=0; i<8; ++i)
1208 int x=ix+nb_xoffset[i], y=iy+nb_yoffset[i];
1211 { x+=nside_; nbnum-=1; }
1213 { x-=nside_; nbnum+=1; }
1215 { y+=nside_; nbnum-=3; }
1217 { y-=nside_; nbnum+=3; }
1219 int f = nb_facearray[nbnum][face_num];
1222 int bits = nb_swaparray[nbnum][face_num>>2];
1223 if (bits&1) x=nside_-x-1;
1224 if (bits&2) y=nside_-y-1;
1225 if (bits&4) std::swap(x,y);
1226 result[i] = (scheme_==
RING) ? xyf2ring(x,y,f) : xyf2nest(x,y,f);
1235 fix_arr<I,4> &pix, fix_arr<double,4> &wgt)
const 1237 planck_assert((ptg.theta>=0)&&(ptg.theta<=pi),
"invalid theta value");
1238 double z = cos (ptg.theta);
1239 I ir1 = ring_above(z);
1241 double theta1, theta2, w1, tmp, dphi;
1247 get_ring_info2 (ir1, sp, nr, theta1, shift);
1249 tmp = (ptg.phi/dphi - .5*shift);
1250 i1 = (tmp<0) ? I(tmp)-1 : I(tmp);
1251 w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
1254 if (i2>=nr) i2 -=nr;
1255 pix[0] = sp+i1; pix[1] = sp+i2;
1256 wgt[0] = 1-w1; wgt[1] = w1;
1260 get_ring_info2 (ir2, sp, nr, theta2, shift);
1262 tmp = (ptg.phi/dphi - .5*shift);
1263 i1 = (tmp<0) ? I(tmp)-1 : I(tmp);
1264 w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
1267 if (i2>=nr) i2 -=nr;
1268 pix[2] = sp+i1; pix[3] = sp+i2;
1269 wgt[2] = 1-w1; wgt[3] = w1;
1274 double wtheta = ptg.theta/theta2;
1275 wgt[2] *= wtheta; wgt[3] *= wtheta;
1276 double fac = (1-wtheta)*0.25;
1277 wgt[0] = fac; wgt[1] = fac; wgt[2] += fac; wgt[3] +=fac;
1278 pix[0] = (pix[2]+2)&3;
1279 pix[1] = (pix[3]+2)&3;
1281 else if (ir2==4*nside_)
1283 double wtheta = (ptg.theta-theta1)/(pi-theta1);
1284 wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
1285 double fac = wtheta*0.25;
1286 wgt[0] += fac; wgt[1] += fac; wgt[2] = fac; wgt[3] =fac;
1287 pix[2] = ((pix[0]+2)&3)+npix_-4;
1288 pix[3] = ((pix[1]+2)&3)+npix_-4;
1292 double wtheta = (ptg.theta-theta1)/(theta2-theta1);
1293 wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
1294 wgt[2] *= wtheta; wgt[3] *= wtheta;
1298 for (tsize m=0; m<pix.size(); ++m)
1299 pix[m] = ring2nest(pix[m]);
1304 std::swap(order_,other.
order_);
1305 std::swap(nside_,other.
nside_);
1306 std::swap(npface_,other.npface_);
1307 std::swap(ncap_,other.ncap_);
1308 std::swap(npix_,other.npix_);
1309 std::swap(fact1_,other.fact1_);
1310 std::swap(fact2_,other.fact2_);
1311 std::swap(scheme_,other.
scheme_);
1317 va.set_z_phi (2./3., pi/(4*nside_));
1318 double t1 = 1.-1./nside_;
1320 vb.set_z_phi (1-t1/3, 0);
1321 return v_angle(va,vb);
1326 if (ring>=2*nside_) ring=4*nside_-ring;
1327 double z=ring2z(ring), z_up=ring2z(ring-1);
1329 uppos.set_z_phi(z_up,0);
1332 mypos.set_z_phi(z,pi/(4*ring));
1333 double v1=v_angle(mypos,uppos);
1334 if (ring!=1)
return v1;
1335 uppos.set_z_phi(ring2z(ring+1),pi/(4*(min(nside_,ring+1))));
1336 return max(v1,v_angle(mypos,uppos));
1338 mypos.set_z_phi(z,0);
1339 double vdist=v_angle(mypos,uppos);
1340 double hdist=sqrt(1.-z*z)*pi/(4*nside_);
1341 return max(hdist,vdist);
1345 int face,
double &z,
double &phi,
double &sth,
bool &have_sth)
const 1348 double jr = jrll[face] - x - y;
1353 double tmp = nr*nr/3.;
1357 sth = std::sqrt(tmp*(2.0-tmp));
1364 double tmp = nr*nr/3.;
1368 sth = std::sqrt(tmp*(2.-tmp));
1378 double tmp=jpll[face]*nr+x-y;
1381 phi = (nr<1e-15) ? 0 : (0.5*halfpi*tmp)/nr;
1386 vec3 locToVec3 (
double z,
double phi,
double sth,
bool have_sth)
1389 return vec3(sth*cos(phi),sth*sin(phi),z);
1393 res.set_z_phi (z, phi);
1401 vector<vec3> &out)
const 1405 pix2xyf(pix, ix, iy, face);
1406 double dc = 0.5 / nside_;
1407 double xc = (ix + 0.5)/nside_, yc = (iy + 0.5)/nside_;
1408 double d = 1.0/(step*nside_);
1409 for (tsize i=0; i<step; ++i)
1413 xyf2loc(xc+dc-i*d, yc+dc, face, z, phi, sth, have_sth);
1414 out[i] = locToVec3(z, phi, sth, have_sth);
1415 xyf2loc(xc-dc, yc+dc-i*d, face, z, phi, sth, have_sth);
1416 out[i+step] = locToVec3(z, phi, sth, have_sth);
1417 xyf2loc(xc-dc+i*d, yc-dc, face, z, phi, sth, have_sth);
1418 out[i+2*step] = locToVec3(z, phi, sth, have_sth);
1419 xyf2loc(xc+dc, yc-dc+i*d, face, z, phi, sth, have_sth);
1420 out[i+3*step] = locToVec3(z, phi, sth, have_sth);
1426 planck_assert(order_>=0,
"need hierarchical map");
1427 planck_assert(order_<=13,
"map too large");
1428 arr<int> result(swap_clen[order_]);
1430 for (
int m=0; m<order_;++m) ofs+=swap_clen[m];
1431 for (tsize m=0; m<result.size();++m) result[m]=swap_cycle[m+ofs];
I nest2peano(I pix) const
void query_disc(pointing ptg, double radius, rangeset< I > &pixset) const
void get_ring_info2(I ring, I &startpix, I &ringpix, double &theta, bool &shifted) const
void query_polygon_inclusive(const std::vector< pointing > &vertex, rangeset< I > &pixset, int fact=1) const
void query_polygon(const std::vector< pointing > &vertex, rangeset< I > &pixset) const
static int nside2order(I nside)
void get_interpol(const pointing &ptg, fix_arr< I, 4 > &pix, fix_arr< double, 4 > &wgt) const
void SetNside(I nside, Healpix_Ordering_Scheme scheme)
void swap(T_Healpix_Base &other)
void Set(int order, Healpix_Ordering_Scheme scheme)
void query_strip(double theta1, double theta2, bool inclusive, rangeset< I > &pixset) const
void pix2zphi(I pix, double &z, double &phi) const
void boundaries(I pix, tsize step, std::vector< vec3 > &out) const
static I npix2nside(I npix)
void get_ring_info(I ring, I &startpix, I &ringpix, double &costheta, double &sintheta, bool &shifted) const
double max_pixrad() const
I ring_above(double z) const
void query_disc_inclusive(pointing ptg, double radius, rangeset< I > &pixset, int fact=1) const
void get_ring_info_small(I ring, I &startpix, I &ringpix, bool &shifted) const
void neighbors(I pix, fix_arr< I, 8 > &result) const
I peano2nest(I pix) const
double ring2z(I ring) const
Healpix_Ordering_Scheme scheme_