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 "healpix_base.h"
00033 #include "cxxutils.h"
00034 #include "pointing.h"
00035 #include "arr.h"
00036
00037 using namespace std;
00038
00039 short Healpix_Base::ctab[];
00040 short Healpix_Base::utab[];
00041
00042 const nside_dummy SET_NSIDE=nside_dummy();
00043
00044 Healpix_Base::Tablefiller::Tablefiller()
00045 {
00046 for (int m=0; m<0x100; ++m)
00047 {
00048 ctab[m] =
00049 (m&0x1 ) | ((m&0x2 ) << 7) | ((m&0x4 ) >> 1) | ((m&0x8 ) << 6)
00050 | ((m&0x10) >> 2) | ((m&0x20) << 5) | ((m&0x40) >> 3) | ((m&0x80) << 4);
00051 utab[m] =
00052 (m&0x1 ) | ((m&0x2 ) << 1) | ((m&0x4 ) << 2) | ((m&0x8 ) << 3)
00053 | ((m&0x10) << 4) | ((m&0x20) << 5) | ((m&0x40) << 6) | ((m&0x80) << 7);
00054 }
00055 }
00056
00057 Healpix_Base::Tablefiller Healpix_Base::Filler;
00058
00059 const int Healpix_Base::jrll[] = { 2,2,2,2,3,3,3,3,4,4,4,4 };
00060 const int Healpix_Base::jpll[] = { 1,3,5,7,0,2,4,6,1,3,5,7 };
00061
00062 int Healpix_Base::nside2order (int nside)
00063 {
00064 for (int m=0; m<=order_max; ++m)
00065 {
00066 int nstest = 1<<m;
00067 if (nside == nstest) return m;
00068 if (nside < nstest) return -1;
00069 }
00070 return -1;
00071 }
00072 int Healpix_Base::npix2nside (int npix)
00073 {
00074 int res=isqrt(npix/12);
00075 planck_assert (npix==res*res*12, "npix2nside: invalid argument");
00076 return res;
00077 }
00078
00079 int Healpix_Base::xy2pix (int x, int y)
00080 {
00081 return utab[x&0xff] | (utab[x>>8]<<16) | (utab[y&0xff]<<1) | (utab[y>>8]<<17);
00082 }
00083 int Healpix_Base::x2pix (int x)
00084 {
00085 return utab[x&0xff] | (utab[x>>8]<<16);
00086 }
00087 int Healpix_Base::y2pix (int y)
00088 {
00089 return (utab[y&0xff]<<1) | (utab[y>>8]<<17);
00090 }
00091
00092 void Healpix_Base::pix2xy (int pix, int &x, int &y)
00093 {
00094 int raw = (pix&0x5555) | ((pix&0x55550000)>>15);
00095 x = ctab[raw&0xff] | (ctab[raw>>8]<<4);
00096 raw = ((pix&0xaaaa)>>1) | ((pix&0xaaaa0000)>>16);
00097 y = ctab[raw&0xff] | (ctab[raw>>8]<<4);
00098 }
00099
00100 int Healpix_Base::ring_above (double z) const
00101 {
00102 double az=abs(z);
00103 if (az>twothird)
00104 {
00105 int iring = int(nside_*sqrt(3*(1-az)));
00106 return (z>0) ? iring : 4*nside_-iring-1;
00107 }
00108 else
00109 return int(nside_*(2-1.5*z));
00110 }
00111
00112 void Healpix_Base::in_ring(int iz, double phi0, double dphi,
00113 vector<int> &listir) const
00114 {
00115 int nr, ir, ipix1;
00116 double shift=0.5;
00117
00118 if (iz<nside_)
00119 {
00120 ir = iz;
00121 nr = ir*4;
00122 ipix1 = 2*ir*(ir-1);
00123 }
00124 else if (iz>(3*nside_))
00125 {
00126 ir = 4*nside_ - iz;
00127 nr = ir*4;
00128 ipix1 = npix_ - 2*ir*(ir+1);
00129 }
00130 else
00131 {
00132 ir = iz - nside_ + 1;
00133 nr = nside_*4;
00134 if ((ir&1)==0) shift = 0;
00135 ipix1 = ncap_ + (ir-1)*nr;
00136 }
00137
00138 int ipix2 = ipix1 + nr - 1;
00139
00140
00141 if (dphi > (pi-1e-7))
00142 for (int i=ipix1; i<=ipix2; ++i) listir.push_back(i);
00143 else
00144 {
00145 int ip_lo = intfloor(nr*inv_twopi*(phi0-dphi) - shift)+1;
00146 int ip_hi = intfloor(nr*inv_twopi*(phi0+dphi) - shift);
00147 int pixnum = ip_lo+ipix1;
00148 if (pixnum<ipix1) pixnum += nr;
00149 for (int i=ip_lo; i<=ip_hi; ++i, ++pixnum)
00150 {
00151 if (pixnum>ipix2) pixnum -= nr;
00152 listir.push_back(pixnum);
00153 }
00154 }
00155 }
00156
00157 void Healpix_Base::nest2xyf (int pix, int &ix, int &iy, int &face_num) const
00158 {
00159 face_num = pix>>(2*order_);
00160 pix2xy(pix&(npface_-1),ix,iy);
00161 }
00162
00163 int Healpix_Base::xyf2nest (int ix, int iy, int face_num) const
00164 {
00165 return (face_num<<(2*order_))+xy2pix(ix,iy);
00166 }
00167
00168 void Healpix_Base::ring2xyf (int pix, int &ix, int &iy, int &face_num) const
00169 {
00170 int iring, iphi, kshift, nr;
00171
00172 int nl2 = 2*nside_;
00173
00174 if (pix<ncap_)
00175 {
00176 iring = int(0.5*(1+isqrt(1+2*pix)));
00177 iphi = (pix+1) - 2*iring*(iring-1);
00178 kshift = 0;
00179 nr = iring;
00180 face_num=0;
00181 int tmp = iphi-1;
00182 if (tmp>=(2*iring))
00183 {
00184 face_num=2;
00185 tmp-=2*iring;
00186 }
00187 if (tmp>=iring) ++face_num;
00188 }
00189 else if (pix<(npix_-ncap_))
00190 {
00191 int ip = pix - ncap_;
00192 if (order_>=0)
00193 {
00194 iring = (ip>>(order_+2)) + nside_;
00195 iphi = (ip&(4*nside_-1)) + 1;
00196 }
00197 else
00198 {
00199 iring = (ip/(4*nside_)) + nside_;
00200 iphi = (ip%(4*nside_)) + 1;
00201 }
00202 kshift = (iring+nside_)&1;
00203 nr = nside_;
00204 unsigned int ire = iring-nside_+1;
00205 unsigned int irm = nl2+2-ire;
00206 int ifm, ifp;
00207 if (order_>=0)
00208 {
00209 ifm = (iphi - ire/2 + nside_ -1) >> order_;
00210 ifp = (iphi - irm/2 + nside_ -1) >> order_;
00211 }
00212 else
00213 {
00214 ifm = (iphi - ire/2 + nside_ -1) / nside_;
00215 ifp = (iphi - irm/2 + nside_ -1) / nside_;
00216 }
00217 if (ifp == ifm)
00218 face_num = (ifp==4) ? 4 : ifp+4;
00219 else if (ifp<ifm)
00220 face_num = ifp;
00221 else
00222 face_num = ifm + 8;
00223 }
00224 else
00225 {
00226 int ip = npix_ - pix;
00227 iring = int(0.5*(1+isqrt(2*ip-1)));
00228 iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
00229 kshift = 0;
00230 nr = iring;
00231 iring = 2*nl2-iring;
00232 face_num=8;
00233 int tmp = iphi-1;
00234 if (tmp>=(2*nr))
00235 {
00236 face_num=10;
00237 tmp-=2*nr;
00238 }
00239 if (tmp>=nr) ++face_num;
00240 }
00241
00242 int irt = iring - (jrll[face_num]*nside_) + 1;
00243 int ipt = 2*iphi- jpll[face_num]*nr - kshift -1;
00244 if (ipt>=nl2) ipt-=8*nside_;
00245
00246 ix = (ipt-irt) >>1;
00247 iy =(-(ipt+irt))>>1;
00248 }
00249
00250 int Healpix_Base::xyf2ring (int ix, int iy, int face_num) const
00251 {
00252 int nl4 = 4*nside_;
00253 int jr = (jrll[face_num]*nside_) - ix - iy - 1;
00254
00255 int nr, kshift, n_before;
00256 if (jr<nside_)
00257 {
00258 nr = jr;
00259 n_before = 2*nr*(nr-1);
00260 kshift = 0;
00261 }
00262 else if (jr > 3*nside_)
00263 {
00264 nr = nl4-jr;
00265 n_before = npix_ - 2*(nr+1)*nr;
00266 kshift = 0;
00267 }
00268 else
00269 {
00270 nr = nside_;
00271 n_before = ncap_ + (jr-nside_)*nl4;
00272 kshift = (jr-nside_)&1;
00273 }
00274
00275 int jp = (jpll[face_num]*nr + ix - iy + 1 + kshift) / 2;
00276 if (jp>nl4)
00277 jp-=nl4;
00278 else
00279 if (jp<1) jp+=nl4;
00280
00281 return n_before + jp - 1;
00282 }
00283
00284 int Healpix_Base::nest2ring (int pix) const
00285 {
00286 planck_assert(order_>=0, "nest2ring: need hierarchical map");
00287 int ix, iy, face_num;
00288 nest2xyf (pix, ix, iy, face_num);
00289 return xyf2ring (ix, iy, face_num);
00290 }
00291
00292 int Healpix_Base::ring2nest (int pix) const
00293 {
00294 planck_assert(order_>=0, "ring2nest: need hierarchical map");
00295 int ix, iy, face_num;
00296 ring2xyf (pix, ix, iy, face_num);
00297 return xyf2nest (ix, iy, face_num);
00298 }
00299
00300 int Healpix_Base::ang2pix_z_phi (double z, double phi) const
00301 {
00302 double za = abs(z);
00303 double tt = modulo(phi,twopi) * inv_halfpi;
00304
00305 if (scheme_==RING)
00306 {
00307 if (za<=twothird)
00308 {
00309 double temp1 = nside_*(0.5+tt);
00310 double temp2 = nside_*z*0.75;
00311 int jp = int(temp1-temp2);
00312 int jm = int(temp1+temp2);
00313
00314
00315 int ir = nside_ + 1 + jp - jm;
00316 int kshift = 1-(ir&1);
00317
00318 int ip = (jp+jm-nside_+kshift+1)/2;
00319 ip = modulo(ip,4*nside_);
00320
00321 return ncap_ + (ir-1)*4*nside_ + ip;
00322 }
00323 else
00324 {
00325 double tp = tt-int(tt);
00326 double tmp = nside_*sqrt(3*(1-za));
00327
00328 int jp = int(tp*tmp);
00329 int jm = int((1.0-tp)*tmp);
00330
00331 int ir = jp+jm+1;
00332 int ip = int(tt*ir);
00333 ip = modulo(ip,4*ir);
00334
00335 if (z>0)
00336 return 2*ir*(ir-1) + ip;
00337 else
00338 return npix_ - 2*ir*(ir+1) + ip;
00339 }
00340 }
00341 else
00342 {
00343 const int ns_max = 1<<order_max;
00344 int face_num, ix, iy;
00345
00346 if (za<=twothird)
00347 {
00348 double temp1 = ns_max*(0.5+tt);
00349 double temp2 = ns_max*z*0.75;
00350 int jp = int(temp1-temp2);
00351 int jm = int(temp1+temp2);
00352 int ifp = jp >> order_max;
00353 int ifm = jm >> order_max;
00354 if (ifp == ifm)
00355 face_num = (ifp==4) ? 4: ifp+4;
00356 else if (ifp < ifm)
00357 face_num = ifp;
00358 else
00359 face_num = ifm + 8;
00360
00361 ix = jm & (ns_max-1);
00362 iy = ns_max - (jp & (ns_max-1)) - 1;
00363 }
00364 else
00365 {
00366 int ntt = int(tt);
00367 double tp = tt-ntt;
00368 double tmp = ns_max*sqrt(3*(1-za));
00369
00370 int jp = int(tp*tmp);
00371 int jm = int((1.0-tp)*tmp);
00372 if (jp>=ns_max) jp = ns_max-1;
00373 if (jm>=ns_max) jm = ns_max-1;
00374 if (z >= 0)
00375 {
00376 face_num = ntt;
00377 ix = ns_max - jm - 1;
00378 iy = ns_max - jp - 1;
00379 }
00380 else
00381 {
00382 face_num = ntt + 8;
00383 ix = jp;
00384 iy = jm;
00385 }
00386 }
00387
00388 int ipf = xy2pix (ix, iy);
00389
00390 ipf >>= (2*(order_max-order_));
00391
00392 return ipf + (face_num<<(2*order_));
00393 }
00394 }
00395
00396 pointing Healpix_Base::pix2ang (int pix) const
00397 {
00398 if (scheme_==RING)
00399 {
00400 if (pix<ncap_)
00401 {
00402 int iring = int(0.5*(1+isqrt(1+2*pix)));
00403 int iphi = (pix+1) - 2*iring*(iring-1);
00404
00405 return pointing (acos(1.0 - (iring*iring)*fact2_),
00406 (iphi-0.5) * pi/(2.0*iring));
00407 }
00408 else if (pix<(npix_-ncap_))
00409 {
00410 int ip = pix - ncap_;
00411 int iring = ip/(4*nside_) + nside_;
00412 int iphi = ip%(4*nside_) + 1;
00413
00414 double fodd = ((iring+nside_)&1) ? 1 : 0.5;
00415
00416 int nl2 = 2*nside_;
00417 return pointing (acos((nl2-iring)*fact1_),
00418 (iphi-fodd) * pi/nl2);
00419 }
00420 else
00421 {
00422 int ip = npix_ - pix;
00423 int iring = int(0.5*(1+isqrt(2*ip-1)));
00424 int iphi = 4*iring + 1 - (ip - 2*iring*(iring-1));
00425
00426 return pointing (acos(-1.0 + (iring*iring)*fact2_),
00427 (iphi-0.5) * pi/(2*iring));
00428 }
00429 }
00430 else
00431 {
00432 int nl4 = nside_*4;
00433
00434 int face_num = pix>>(2*order_);
00435 int ipf = pix&(npface_-1);
00436
00437 int ix, iy;
00438 pix2xy(ipf,ix,iy);
00439
00440 int jr = (jrll[face_num]<<order_) - ix - iy - 1;
00441
00442 int nr, kshift;
00443 double z;
00444 if (jr<nside_)
00445 {
00446 nr = jr;
00447 z = 1 - nr*nr*fact2_;
00448 kshift = 0;
00449 }
00450 else if (jr > 3*nside_)
00451 {
00452 nr = nl4-jr;
00453 z = nr*nr*fact2_ - 1;
00454 kshift = 0;
00455 }
00456 else
00457 {
00458 nr = nside_;
00459 z = (2*nside_-jr)*fact1_;
00460 kshift = (jr-nside_)&1;
00461 }
00462
00463 int jp = (jpll[face_num]*nr + ix -iy + 1 + kshift) / 2;
00464 if (jp>nl4) jp-=nl4;
00465 if (jp<1) jp+=nl4;
00466
00467 return pointing (acos(z), (jp-(kshift+1)*0.5)*(halfpi/nr));
00468 }
00469 }
00470
00471 void Healpix_Base::query_disc (const pointing &ptg, double radius,
00472 vector<int>& listpix) const
00473 {
00474 listpix.clear();
00475
00476 double dth1 = fact2_;
00477 double dth2 = fact1_;
00478 double cosang = cos(radius);
00479
00480 double z0 = cos(ptg.theta);
00481 double xa = 1./sqrt((1-z0)*(1+z0));
00482
00483 double rlat1 = ptg.theta - radius;
00484 double zmax = cos(rlat1);
00485 int irmin = ring_above (zmax)+1;
00486
00487 if (rlat1<=0)
00488 for (int m=1; m<irmin; ++m)
00489 in_ring (m, 0, pi, listpix);
00490
00491 double rlat2 = ptg.theta + radius;
00492 double zmin = cos(rlat2);
00493 int irmax = ring_above (zmin);
00494
00495
00496 for (int iz=irmin; iz<=irmax; ++iz)
00497 {
00498 double z;
00499 if (iz<nside_)
00500 z = 1.0 - iz*iz*dth1;
00501 else if (iz <= (3*nside_))
00502 z = (2*nside_-iz) * dth2;
00503 else
00504 z = -1.0 + (4*nside_-iz)*(4*nside_-iz)*dth1;
00505
00506
00507 double x = (cosang-z*z0)*xa;
00508 double ysq = 1-z*z-x*x;
00509 planck_assert(ysq>=0, "error in query_disc()");
00510 double dphi=atan2(sqrt(ysq),x);
00511 in_ring (iz, ptg.phi, dphi, listpix);
00512 }
00513
00514 if (rlat2>=pi)
00515 for (int m=irmax+1; m<(4*nside_); ++m)
00516 in_ring (m, 0, pi, listpix);
00517
00518 if (scheme_==NEST)
00519 for (unsigned int m=0; m<listpix.size(); ++m)
00520 listpix[m] = ring2nest(listpix[m]);
00521 }
00522
00523 void Healpix_Base::get_ring_info (int ring, int &startpix, int &ringpix,
00524 double &costheta, double &sintheta, bool &shifted) const
00525 {
00526 planck_assert(scheme_==RING,"map must be in RING scheme");
00527 int northring = (ring>2*nside_) ? 4*nside_-ring : ring;
00528 if (northring < nside_)
00529 {
00530 costheta = 1 - northring*northring*fact2_;
00531 sintheta = sin(2*asin(northring/(sqrt(6.)*nside_)));
00532 ringpix = 4*northring;
00533 shifted = true;
00534 startpix = 2*northring*(northring-1);
00535 }
00536 else
00537 {
00538 costheta = (2*nside_-northring)*fact1_;
00539 sintheta = sqrt((1+costheta)*(1-costheta));
00540 ringpix = 4*nside_;
00541 shifted = ((northring-nside_) & 1) == 0;
00542 startpix = ncap_ + (northring-nside_)*ringpix;
00543 }
00544 if (northring != ring)
00545 {
00546 costheta = -costheta;
00547 startpix = npix_ - startpix - ringpix;
00548 }
00549 }
00550
00551 void Healpix_Base::neighbors (int pix, fix_arr<int,8> &result) const
00552 {
00553 static const int xoffset[] = { -1,-1, 0, 1, 1, 1, 0,-1 };
00554 static const int yoffset[] = { 0, 1, 1, 1, 0,-1,-1,-1 };
00555 static const int facearray[][12] =
00556 { { 8, 9,10,11,-1,-1,-1,-1,10,11, 8, 9 },
00557 { 5, 6, 7, 4, 8, 9,10,11, 9,10,11, 8 },
00558 { -1,-1,-1,-1, 5, 6, 7, 4,-1,-1,-1,-1 },
00559 { 4, 5, 6, 7,11, 8, 9,10,11, 8, 9,10 },
00560 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 },
00561 { 1, 2, 3, 0, 0, 1, 2, 3, 5, 6, 7, 4 },
00562 { -1,-1,-1,-1, 7, 4, 5, 6,-1,-1,-1,-1 },
00563 { 3, 0, 1, 2, 3, 0, 1, 2, 4, 5, 6, 7 },
00564 { 2, 3, 0, 1,-1,-1,-1,-1, 0, 1, 2, 3 } };
00565 static const int swaparray[][12] =
00566 { { 0,0,0,0,0,0,0,0,3,3,3,3 },
00567 { 0,0,0,0,0,0,0,0,6,6,6,6 },
00568 { 0,0,0,0,0,0,0,0,0,0,0,0 },
00569 { 0,0,0,0,0,0,0,0,5,5,5,5 },
00570 { 0,0,0,0,0,0,0,0,0,0,0,0 },
00571 { 5,5,5,5,0,0,0,0,0,0,0,0 },
00572 { 0,0,0,0,0,0,0,0,0,0,0,0 },
00573 { 6,6,6,6,0,0,0,0,0,0,0,0 },
00574 { 3,3,3,3,0,0,0,0,0,0,0,0 } };
00575
00576 int ix, iy, face_num;
00577 (scheme_==RING) ?
00578 ring2xyf(pix,ix,iy,face_num) : nest2xyf(pix,ix,iy,face_num);
00579
00580 const int nsm1 = nside_-1;
00581 if ((ix>0)&&(ix<nsm1)&&(iy>0)&&(iy<nsm1))
00582 {
00583 if (scheme_==RING)
00584 for (int m=0; m<8; ++m)
00585 result[m] = xyf2ring(ix+xoffset[m],iy+xoffset[m],face_num);
00586 else
00587 for (int m=0; m<8; ++m)
00588 result[m] = xyf2nest(ix+xoffset[m],iy+xoffset[m],face_num);
00589 }
00590 else
00591 {
00592 for (int i=0; i<8; ++i)
00593 {
00594 int x=ix+xoffset[i];
00595 int y=iy+yoffset[i];
00596 int nbnum=4;
00597 if (x<0)
00598 { x+=nside_; nbnum-=1; }
00599 else if (x>=nside_)
00600 { x-=nside_; nbnum+=1; }
00601 if (y<0)
00602 { y+=nside_; nbnum-=3; }
00603 else if (y>=nside_)
00604 { y-=nside_; nbnum+=3; }
00605
00606 int f = facearray[nbnum][face_num];
00607 if (f>=0)
00608 {
00609 if (swaparray[nbnum][face_num]&1) x=nside_-x-1;
00610 if (swaparray[nbnum][face_num]&2) y=nside_-y-1;
00611 if (swaparray[nbnum][face_num]&4) std::swap(x,y);
00612 result[i] = (scheme_==RING) ? xyf2ring(x,y,f) : xyf2nest(x,y,f);
00613 }
00614 else
00615 result[i] = -1;
00616 }
00617 }
00618 }
00619
00620 namespace {
00621
00622 void add_weights (int p1, int p2, int p3, int p4, double xdiff, double ydiff,
00623 fix_arr<int,4> &pix, fix_arr<double,4> &wgt)
00624 {
00625 pix[0] = p1;
00626 pix[1] = p2;
00627 pix[2] = p3;
00628
00629 if (p4>=0)
00630 {
00631 wgt[0] = (1-xdiff)*(1-ydiff);
00632 wgt[1] = xdiff*(1-ydiff);
00633 wgt[2] = ydiff*(1-xdiff);
00634 pix[3] = p4;
00635 wgt[3] = xdiff*ydiff;
00636 }
00637 else
00638 {
00639 wgt[0] = 1-xdiff-ydiff+fourthird*xdiff*ydiff;
00640 wgt[1] = xdiff-twothird*xdiff*ydiff;
00641 wgt[2] = ydiff-twothird*xdiff*ydiff;
00642 pix[3] = 0;
00643 wgt[3] = 0;
00644 }
00645 }
00646
00647 }
00648
00649 void Healpix_Base::get_interpol (const pointing &ptg, fix_arr<int,4> &pix,
00650 fix_arr<double,4> &wgt) const
00651 {
00652 double z = cos(ptg.theta);
00653 double za = abs(z);
00654 double tt = modulo(ptg.phi,twopi) / halfpi;
00655
00656 int face_num;
00657 double ix, iy;
00658 if (za<=twothird)
00659 {
00660 double temp1 = nside_*(0.5+tt);
00661 double temp2 = nside_*z*0.75;
00662 double jp = temp1-temp2;
00663 double jm = temp1+temp2;
00664 int ifp = int(jp/nside_);
00665 int ifm = int(jm/nside_);
00666 if (ifp == ifm)
00667 face_num = (ifp==4) ? 4 : (ifp+4);
00668 else if (ifp < ifm)
00669 face_num = ifp;
00670 else
00671 face_num = ifm + 8;
00672
00673 ix = modulo(jm, double(nside_));
00674 iy = nside_ - modulo(jp, double(nside_));
00675 }
00676 else
00677 {
00678 int ntt = int(tt);
00679 double tp = tt-ntt;
00680 double tmp = nside_*sqrt(3*(1-za));
00681
00682 double jp = tp*tmp;
00683 double jm = (1.0-tp)*tmp;
00684 if (jp>=nside_) jp = nside_;
00685 if (jm>=nside_) jm = nside_;
00686 if (z >= 0)
00687 {
00688 face_num = ntt;
00689 ix = nside_ - jm;
00690 iy = nside_ - jp;
00691 }
00692 else
00693 {
00694 face_num = ntt + 8;
00695 ix = jp;
00696 iy = jm;
00697 }
00698 }
00699
00700 if ((ix>0.5) && (ix<(nside_-0.5)) && (iy>0.5) && (iy<(nside_-0.5)))
00701 {
00702 int xpix=int(ix-0.5), ypix=int(iy-0.5);
00703 double xdiff=ix-0.5-xpix, ydiff=iy-0.5-ypix;
00704 wgt[0] = (1-xdiff)*(1-ydiff);
00705 wgt[1] = xdiff*(1-ydiff);
00706 wgt[2] = (1-xdiff)*ydiff;
00707 wgt[3] = xdiff*ydiff;
00708 if (scheme_==RING)
00709 {
00710 pix[0] = xyf2ring(xpix ,ypix ,face_num);
00711 pix[1] = xyf2ring(xpix+1,ypix ,face_num);
00712 pix[2] = xyf2ring(xpix ,ypix+1,face_num);
00713 pix[3] = xyf2ring(xpix+1,ypix+1,face_num);
00714 }
00715 else
00716 {
00717 pix[0] = xyf2nest(xpix ,ypix ,face_num);
00718 pix[1] = xyf2nest(xpix+1,ypix ,face_num);
00719 pix[2] = xyf2nest(xpix ,ypix+1,face_num);
00720 pix[3] = xyf2nest(xpix+1,ypix+1,face_num);
00721 }
00722 }
00723 else
00724 {
00725 int xpix=int(ix-0.5), ypix=int(iy-0.5);
00726 xpix=max(0,min(nside_-1,xpix));
00727 ypix=max(0,min(nside_-1,ypix));
00728 int pixnr = (scheme_==RING) ?
00729 xyf2ring(xpix,ypix,face_num) : xyf2nest(xpix,ypix,face_num);
00730 fix_arr<int,8> nb;
00731 neighbors (pixnr,nb);
00732
00733 double xdiff=ix-0.5-xpix, ydiff=iy-0.5-ypix;
00734 if (xdiff>0)
00735 {
00736 if (ydiff>0)
00737 add_weights(pixnr,nb[4],nb[2],nb[3], xdiff, ydiff,pix,wgt);
00738 else
00739 add_weights(pixnr,nb[4],nb[6],nb[5], xdiff,-ydiff,pix,wgt);
00740 }
00741 else
00742 {
00743 if (ydiff>0)
00744 add_weights(pixnr,nb[0],nb[2],nb[1],-xdiff, ydiff,pix,wgt);
00745 else
00746 add_weights(pixnr,nb[0],nb[6],nb[7],-xdiff,-ydiff,pix,wgt);
00747 }
00748 }
00749 }
00750
00751 void Healpix_Base::get_ring_info2 (int ring, int &startpix, int &ringpix,
00752 double &theta, bool &shifted) const
00753 {
00754 int northring = (ring>2*nside_) ? 4*nside_-ring : ring;
00755 if (northring < nside_)
00756 {
00757 theta = acos(1 - northring*northring*fact2_);
00758 ringpix = 4*northring;
00759 shifted = true;
00760 startpix = 2*northring*(northring-1);
00761 }
00762 else
00763 {
00764 theta = acos((2*nside_-northring)*fact1_);
00765 ringpix = 4*nside_;
00766 shifted = ((northring-nside_) & 1) == 0;
00767 startpix = ncap_ + (northring-nside_)*ringpix;
00768 }
00769 if (northring != ring)
00770 {
00771 theta = pi-theta;
00772 startpix = npix_ - startpix - ringpix;
00773 }
00774 }
00775
00776 void Healpix_Base::get_interpol2 (const pointing &ptg, fix_arr<int,4> &pix,
00777 fix_arr<double,4> &wgt) const
00778 {
00779 double z = cos (ptg.theta);
00780 int ir1 = ring_above(z);
00781 int ir2 = ir1+1;
00782 double theta1, theta2, w1, tmp, dphi;
00783 int sp,nr;
00784 bool shift;
00785 int i1,i2;
00786 if (ir1>0)
00787 {
00788 get_ring_info2 (ir1, sp, nr, theta1, shift);
00789 dphi = twopi/nr;
00790 tmp = (ptg.phi/dphi - .5*shift);
00791 i1 = (tmp<0) ? int(tmp)-1 : int(tmp);
00792 w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
00793 i2 = i1+1;
00794 if (i1<0) i1 +=nr;
00795 if (i2>=nr) i2 -=nr;
00796 pix[0] = sp+i1; pix[1] = sp+i2;
00797 wgt[0] = 1-w1; wgt[1] = w1;
00798 }
00799 if (ir2<(4*nside_))
00800 {
00801 get_ring_info2 (ir2, sp, nr, theta2, shift);
00802 dphi = twopi/nr;
00803 tmp = (ptg.phi/dphi - .5*shift);
00804 i1 = (tmp<0) ? int(tmp)-1 : int(tmp);
00805 w1 = (ptg.phi-(i1+.5*shift)*dphi)/dphi;
00806 i2 = i1+1;
00807 if (i1<0) i1 +=nr;
00808 if (i2>=nr) i2 -=nr;
00809 pix[2] = sp+i1; pix[3] = sp+i2;
00810 wgt[2] = 1-w1; wgt[3] = w1;
00811 }
00812
00813 if (ir1==0)
00814 {
00815 double wtheta = ptg.theta/theta2;
00816 wgt[2] *= wtheta; wgt[3] *= wtheta;
00817 double fac = (1-wtheta)*0.25;
00818 wgt[0] = fac; wgt[1] = fac; wgt[2] += fac; wgt[3] +=fac;
00819 pix[0] = (pix[2]+2)%4;
00820 pix[1] = (pix[3]+2)%4;
00821 }
00822 else if (ir2==4*nside_)
00823 {
00824 double wtheta = (ptg.theta-theta1)/(pi-theta1);
00825 wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
00826 double fac = wtheta*0.25;
00827 wgt[0] += fac; wgt[1] += fac; wgt[2] = fac; wgt[3] =fac;
00828 pix[2] = ((pix[0]+2)&3)+npix_-4;
00829 pix[3] = ((pix[1]+2)&3)+npix_-4;
00830 }
00831 else
00832 {
00833 double wtheta = (ptg.theta-theta1)/(theta2-theta1);
00834 wgt[0] *= (1-wtheta); wgt[1] *= (1-wtheta);
00835 wgt[2] *= wtheta; wgt[3] *= wtheta;
00836 }
00837
00838 if (scheme_==NEST)
00839 for (int m=0; m<pix.size(); ++m)
00840 pix[m] = ring2nest(pix[m]);
00841 }