moc.h

Go to the documentation of this file.
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 /*! \file moc.h
00028  *  Copyright (C) 2014-2015 Max-Planck-Society
00029  *  \author Martin Reinecke
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     /*! Returns a new Moc that contains the union of this Moc and \a other. */
00091     Moc op_or (const Moc &other) const
00092       { return fromNewRangeSet(rs.op_or(other.rs)); }
00093     /*! Returns a new Moc that contains the intersection of this Moc and
00094         \a other. */
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     /*! Returns a new Moc that contains all parts of this Moc that are not
00100         contained in \a other. */
00101     Moc op_andnot (const Moc &other) const
00102       { return fromNewRangeSet(rs.op_andnot(other.rs)); }
00103     /*! Returns the complement of this Moc. */
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     /** Returns \c true if \a other is a subset of this Moc, else \c false. */
00110     bool contains(const Moc &other) const
00111       { return rs.contains(other.rs); }
00112     /** Returns \c true if the intersection of this Moc and \a other is not
00113         empty. */
00114     bool overlaps(const Moc &other) const
00115       { return rs.overlaps(other.rs); }
00116 
00117     /** Returns a vector containing all HEALPix pixels (in ascending NUNIQ
00118         order) covered by this Moc. The result is well-formed in the sense that
00119         every pixel is given at its lowest possible HEALPix order. */
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

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