moc.h
Go to the documentation of this file.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 #ifndef HEALPIX_MOC_H
00033 #define HEALPIX_MOC_H
00034
00035 #include "healpix_base.h"
00036 #include "compress_utils.h"
00037
00038 template<typename I> class Moc
00039 {
00040 public:
00041 enum{maxorder=T_Healpix_Base<I>::order_max};
00042
00043 private:
00044 rangeset<I> rs;
00045
00046 static Moc fromNewRangeSet(const rangeset<I> &rngset)
00047 {
00048 Moc res;
00049 res.rs = rngset;
00050 return res;
00051 }
00052
00053 public:
00054 const rangeset<I> &Rs() { return rs; }
00055 tsize maxOrder() const
00056 {
00057 I combo=0;
00058 for (tsize i=0; i<rs.nranges(); ++i)
00059 combo|=rs.ivbegin(i)|rs.ivend(i);
00060 return maxorder-(trailingZeros(combo)>>1);
00061 }
00062 Moc degradedToOrder (int order, bool keepPartialCells) const
00063 {
00064 int shift=2*(maxorder-order);
00065 I ofs=(I(1)<<shift)-1;
00066 I mask = ~ofs;
00067 I adda = keepPartialCells ? I(0) : ofs,
00068 addb = keepPartialCells ? ofs : I(0);
00069 rangeset<I> rs2;
00070 for (tsize i=0; i<rs.nranges(); ++i)
00071 {
00072 I a=(rs.ivbegin(i)+adda)&mask;
00073 I b=(rs.ivend (i)+addb)&mask;
00074 if (b>a) rs2.append(a,b);
00075 }
00076 return fromNewRangeSet(rs2);
00077 }
00078 void addPixelRange (int order, I p1, I p2)
00079 {
00080 int shift=2*(maxorder-order);
00081 rs.add(p1<<shift,p2<<shift);
00082 }
00083 void appendPixelRange (int order, I p1, I p2)
00084 {
00085 int shift=2*(maxorder-order);
00086 rs.append(p1<<shift,p2<<shift);
00087 }
00088 void appendPixel (int order, I p)
00089 { appendPixelRange(order,p,p+1); }
00090
00091 Moc op_or (const Moc &other) const
00092 { return fromNewRangeSet(rs.op_or(other.rs)); }
00093
00094
00095 Moc op_and (const Moc &other) const
00096 { return fromNewRangeSet(rs.op_and(other.rs)); }
00097 Moc op_xor (const Moc &other) const
00098 { return fromNewRangeSet(rs.op_xor(other.rs)); }
00099
00100
00101 Moc op_andnot (const Moc &other) const
00102 { return fromNewRangeSet(rs.op_andnot(other.rs)); }
00103
00104 Moc complement() const
00105 {
00106 rangeset<I> full; full.append(I(0),I(12)*(I(1)<<(2*maxorder)));
00107 return fromNewRangeSet(full.op_andnot(rs));
00108 }
00109
00110 bool contains(const Moc &other) const
00111 { return rs.contains(other.rs); }
00112
00113
00114 bool overlaps(const Moc &other) const
00115 { return rs.overlaps(other.rs); }
00116
00117
00118
00119
00120 std::vector<I> toUniq() const
00121 {
00122 std::vector<I> res;
00123 std::vector<std::vector<I> > buf(maxorder+1);
00124 for (tsize i=0; i<rs.nranges(); ++i)
00125 {
00126 I start=rs.ivbegin(i), end=rs.ivend(i);
00127 while(start!=end)
00128 {
00129 int logstep=std::min<int>(maxorder,trailingZeros(start)>>1);
00130 logstep=std::min(logstep,ilog2(end-start)>>1);
00131 buf[maxorder-logstep].push_back(start);
00132 start+=I(1)<<(2*logstep);
00133 }
00134 }
00135 for (int o=0; o<=maxorder; ++o)
00136 {
00137 I ofs=I(1)<<(2*o+2);
00138 int shift=2*(maxorder-o);
00139 for (tsize j=0; j<buf[o].size(); ++j)
00140 res.push_back((buf[o][j]>>shift)+ofs);
00141 }
00142 return res;
00143 }
00144
00145 static Moc fromUniq (const std::vector<I> &vu)
00146 {
00147 rangeset<I> r, rtmp;
00148 int lastorder=0;
00149 int shift=2*maxorder;
00150 for (tsize i=0; i<vu.size(); ++i)
00151 {
00152 int order = ilog2(vu[i]>>2)>>1;
00153 if (order!=lastorder)
00154 {
00155 r=r.op_or(rtmp);
00156 rtmp.clear();
00157 lastorder=order;
00158 shift=2*(maxorder-order);
00159 }
00160 I pix = vu[i]-(I(1)<<(2*order+2));
00161 rtmp.append (pix<<shift,(pix+1)<<shift);
00162 }
00163 r=r.op_or(rtmp);
00164 return fromNewRangeSet(r);
00165 }
00166
00167 static void uniq_nest2peano(std::vector<I> &vu)
00168 {
00169 using namespace std;
00170 if (vu.empty()) return;
00171
00172 tsize start=0;
00173 int order=-1;
00174 T_Healpix_Base<I> base;
00175 I offset=0;
00176 for (tsize j=0; j<vu.size(); ++j)
00177 {
00178 int neworder=ilog2(vu[j]>>2)>>1;
00179 if (neworder>order)
00180 {
00181 sort(vu.begin()+start,vu.begin()+j);
00182 order=neworder;
00183 start=j;
00184 base.Set(order,NEST);
00185 offset=I(1)<<(2*order+2);
00186 }
00187 vu[j]=base.nest2peano(vu[j]-offset)+offset;
00188 }
00189 sort(vu.begin()+start,vu.end());
00190 }
00191 static void uniq_peano2nest(std::vector<I> &vu)
00192 {
00193 using namespace std;
00194 if (vu.empty()) return;
00195
00196 tsize start=0;
00197 int order=-1;
00198 T_Healpix_Base<I> base;
00199 I offset=0;
00200 for (tsize j=0; j<vu.size(); ++j)
00201 {
00202 int neworder=ilog2(vu[j]>>2)>>1;
00203 if (neworder>order)
00204 {
00205 sort(vu.begin()+start,vu.begin()+j);
00206 order=neworder;
00207 start=j;
00208 base.Set(order,NEST);
00209 offset=I(1)<<(2*order+2);
00210 }
00211 vu[j]=base.peano2nest(vu[j]-offset)+offset;
00212 }
00213 sort(vu.begin()+start,vu.end());
00214 }
00215
00216 std::vector<uint8> toCompressed() const
00217 {
00218 obitstream obs;
00219 interpol_encode(rs.data().begin(),rs.data().end(),obs);
00220 return obs.state();
00221 }
00222 static Moc fromCompressed(const std::vector<uint8> &data)
00223 {
00224 ibitstream ibs(data);
00225 std::vector<I> v;
00226 interpol_decode(v,ibs);
00227 Moc out;
00228 out.rs.setData(v);
00229 return out;
00230 }
00231
00232 bool operator==(const Moc &other) const
00233 {
00234 if (this == &other)
00235 return true;
00236 return rs==other.rs;
00237 }
00238
00239 tsize nranges() const
00240 { return rs.nranges(); }
00241 I nval() const
00242 { return rs.nval(); }
00243 };
00244
00245 #endif