35 #include "lsconstants.h" 41 double pseudodist(
const vec3 &v1,
const vec3 &v2)
42 {
return (v1-v2).SquaredLength(); }
43 double dist2pseudodist(
double pdist)
44 {
double tmp=2*sin(0.5*pdist);
return tmp*tmp; }
45 double pseudodist2dist(
double dist)
46 {
return 2*asin(sqrt(dist)*0.5); }
52 constexpr
int FULLY_IN_MASK=1;
53 constexpr
int BORDER=2;
54 int maxord = mask.
Order();
55 planck_assert(maxord>=0,
"Nside must be a power of 2");
60 orders={(maxord+1)/2, maxord};
61 vector<Healpix_Map<uint8>> omask;
63 for (
size_t i=0; i<orders.size(); ++i)
65 omask.emplace_back(orders[i],
NEST);
66 buf.push_back(2*omask[i].max_pixrad());
68 auto &maxmask(omask.back());
70 #pragma omp parallel
for schedule(
static)
71 for (
int i=0; i<mask.
Npix(); ++i)
72 maxmask[i] = (mask[mask.
nest2ring(i)]==0) ? FULLY_IN_MASK : 0;
74 #pragma omp parallel for schedule(static) 75 for (
int i=0; i<mask.
Npix(); ++i)
76 maxmask[i] = (mask[i]==0) ? FULLY_IN_MASK : 0;
78 #pragma omp parallel for schedule(dynamic,10000) 79 for (
int i=0; i<mask.
Npix(); ++i)
83 maxmask.neighbors(i, nb);
84 for (
size_t j=0; j<8; ++j)
85 if ((nb[j]!=-1) && (maxmask[nb[j]]==0))
93 for (
int j=omask.size()-2; j>=0; --j)
95 int fct = 1<<(2*(omask[j+1].Order()-omask[j].Order()));
96 #pragma omp parallel for schedule(static) 97 for (
int i=0; i<omask[j].Npix(); ++i)
100 for (
int k=0; k<fct; ++k)
102 And &= omask[j+1][fct*i+k];
103 Or |= omask[j+1][fct*i+k];
105 omask[j][i] = (And&FULLY_IN_MASK) | (Or&BORDER);
110 #pragma omp parallel for schedule(static) 111 for (
int i=0; i<mask.
Npix(); ++i)
112 tdist[i] = (maxmask[i]>0) ? 0. : maxdist;
114 function<void(int, int, const vector<int> &,
const vector<vec3> &)> process;
115 process = [&omask,&tdist,maxord,&process,&buf,maxdist]
116 (
int oo,
int pix,
const vector<int> &submask,
const vector<vec3> &subvec)->
void 118 int order=omask[oo].Order();
119 if (submask.empty())
return;
120 if (omask[oo][pix]&FULLY_IN_MASK)
return;
121 vec3 v=omask[oo].pix2vec(pix);
125 for (
auto subv:subvec)
126 pd=min(pd, pseudodist(subv, v));
127 tdist[pix]=min(maxdist,pseudodist2dist(pd));
130 vector<double> psubdist(submask.size());
132 for (
size_t i=0; i<submask.size(); ++i)
134 psubdist[i] = pseudodist(v, subvec[i]);
135 pdlim = min(pdlim,psubdist[i]);
138 double lim0=dist2pseudodist(min(pi,maxdist+buf[oo]));
139 if (pdlim>lim0)
return;
140 double lim1=dist2pseudodist(min(pi,pseudodist2dist(pdlim)+2*buf[oo]));
142 vector<int> submask2;
143 vector<vec3> subvec2;
144 int fct = 1<<(2*(omask[oo+1].Order()-omask[oo].Order()));
145 for (
size_t i=0; i<submask.size(); ++i)
146 if (psubdist[i]<lim1)
147 if (psubdist[i]<lim0)
148 for (
int j=submask[i]*fct; j<(submask[i]+1)*fct; ++j)
149 if (omask[oo+1][j]&BORDER)
151 submask2.push_back(j);
152 subvec2.push_back(omask[oo+1].pix2vec(j));
154 for (
int pix2=pix*fct; pix2<(pix+1)*fct; ++pix2)
155 process(oo+1, pix2, submask2, subvec2);
160 for (
int i=0; i<omask[0].Npix(); ++i)
161 if (omask[0][i]&BORDER)
163 submask.push_back(i);
164 subvec.push_back(omask[0].pix2vec(i));
166 #pragma omp parallel for schedule(dynamic) 167 for (
int i=0; i<omask[0].Npix(); ++i)
168 process(0, i, submask, subvec);
Healpix_Ordering_Scheme Scheme() const