Healpix C++  3.83
moc.h
Go to the documentation of this file.
1 /*
2  * This file is part of Healpix_cxx.
3  *
4  * Healpix_cxx is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * Healpix_cxx is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Healpix_cxx; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * For more information about HEALPix, see http://healpix.sourceforge.net
19  */
20 
21 /*
22  * Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
23  * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
24  * (DLR).
25  */
26 
27 /*! \file moc.h
28  * Copyright (C) 2014-2015 Max-Planck-Society
29  * \author Martin Reinecke
30  */
31 
32 #ifndef HEALPIX_MOC_H
33 #define HEALPIX_MOC_H
34 
35 #include "healpix_base.h"
36 #include "compress_utils.h"
37 
38 template<typename I> class Moc
39  {
40  public:
41  enum{maxorder=T_Healpix_Base<I>::order_max};
42 
43  private:
44  rangeset<I> rs;
45 
46  static Moc fromNewRangeSet(const rangeset<I> &rngset)
47  {
48  Moc res;
49  res.rs = rngset;
50  return res;
51  }
52 
53  public:
54  const rangeset<I> &Rs() { return rs; }
55  tsize maxOrder() const
56  {
57  I combo=0;
58  for (tsize i=0; i<rs.nranges(); ++i)
59  combo|=rs.ivbegin(i)|rs.ivend(i);
60  return maxorder-(trailingZeros(combo)>>1);
61  }
62  Moc degradedToOrder (int order, bool keepPartialCells) const
63  {
64  int shift=2*(maxorder-order);
65  I ofs=(I(1)<<shift)-1;
66  I mask = ~ofs;
67  I adda = keepPartialCells ? I(0) : ofs,
68  addb = keepPartialCells ? ofs : I(0);
69  rangeset<I> rs2;
70  for (tsize i=0; i<rs.nranges(); ++i)
71  {
72  I a=(rs.ivbegin(i)+adda)&mask;
73  I b=(rs.ivend (i)+addb)&mask;
74  if (b>a) rs2.append(a,b);
75  }
76  return fromNewRangeSet(rs2);
77  }
78  void addPixelRange (int order, I p1, I p2)
79  {
80  int shift=2*(maxorder-order);
81  rs.add(p1<<shift,p2<<shift);
82  }
83  void appendPixelRange (int order, I p1, I p2)
84  {
85  int shift=2*(maxorder-order);
86  rs.append(p1<<shift,p2<<shift);
87  }
88  void appendPixel (int order, I p)
89  { appendPixelRange(order,p,p+1); }
90  /*! Returns a new Moc that contains the union of this Moc and \a other. */
91  Moc op_or (const Moc &other) const
92  { return fromNewRangeSet(rs.op_or(other.rs)); }
93  /*! Returns a new Moc that contains the intersection of this Moc and
94  \a other. */
95  Moc op_and (const Moc &other) const
96  { return fromNewRangeSet(rs.op_and(other.rs)); }
97  Moc op_xor (const Moc &other) const
98  { return fromNewRangeSet(rs.op_xor(other.rs)); }
99  /*! Returns a new Moc that contains all parts of this Moc that are not
100  contained in \a other. */
101  Moc op_andnot (const Moc &other) const
102  { return fromNewRangeSet(rs.op_andnot(other.rs)); }
103  /*! Returns the complement of this Moc. */
104  Moc complement() const
105  {
106  rangeset<I> full; full.append(I(0),I(12)*(I(1)<<(2*maxorder)));
107  return fromNewRangeSet(full.op_andnot(rs));
108  }
109  /** Returns \c true if \a other is a subset of this Moc, else \c false. */
110  bool contains(const Moc &other) const
111  { return rs.contains(other.rs); }
112  /** Returns \c true if the intersection of this Moc and \a other is not
113  empty. */
114  bool overlaps(const Moc &other) const
115  { return rs.overlaps(other.rs); }
116 
117  /** Returns a vector containing all HEALPix pixels (in ascending NUNIQ
118  order) covered by this Moc. The result is well-formed in the sense that
119  every pixel is given at its lowest possible HEALPix order. */
120  std::vector<I> toUniq() const
121  {
122  std::vector<I> res;
123  std::vector<std::vector<I> > buf(maxorder+1);
124  for (tsize i=0; i<rs.nranges(); ++i)
125  {
126  I start=rs.ivbegin(i), end=rs.ivend(i);
127  while(start!=end)
128  {
129  int logstep=std::min<int>(maxorder,trailingZeros(start)>>1);
130  logstep=std::min(logstep,ilog2(end-start)>>1);
131  buf[maxorder-logstep].push_back(start);
132  start+=I(1)<<(2*logstep);
133  }
134  }
135  for (int o=0; o<=maxorder; ++o)
136  {
137  I ofs=I(1)<<(2*o+2);
138  int shift=2*(maxorder-o);
139  for (tsize j=0; j<buf[o].size(); ++j)
140  res.push_back((buf[o][j]>>shift)+ofs);
141  }
142  return res;
143  }
144 
145  static Moc fromUniq (const std::vector<I> &vu)
146  {
147  rangeset<I> r, rtmp;
148  int lastorder=0;
149  int shift=2*maxorder;
150  for (tsize i=0; i<vu.size(); ++i)
151  {
152  int order = ilog2(vu[i]>>2)>>1;
153  if (order!=lastorder)
154  {
155  r=r.op_or(rtmp);
156  rtmp.clear();
157  lastorder=order;
158  shift=2*(maxorder-order);
159  }
160  I pix = vu[i]-(I(1)<<(2*order+2));
161  rtmp.append (pix<<shift,(pix+1)<<shift);
162  }
163  r=r.op_or(rtmp);
164  return fromNewRangeSet(r);
165  }
166 
167  static void uniq_nest2peano(std::vector<I> &vu)
168  {
169  using namespace std;
170  if (vu.empty()) return;
171 
172  tsize start=0;
173  int order=-1;
174  T_Healpix_Base<I> base;
175  I offset=0;
176  for (tsize j=0; j<vu.size(); ++j)
177  {
178  int neworder=ilog2(vu[j]>>2)>>1;
179  if (neworder>order)
180  {
181  sort(vu.begin()+start,vu.begin()+j);
182  order=neworder;
183  start=j;
184  base.Set(order,NEST);
185  offset=I(1)<<(2*order+2);
186  }
187  vu[j]=base.nest2peano(vu[j]-offset)+offset;
188  }
189  sort(vu.begin()+start,vu.end());
190  }
191  static void uniq_peano2nest(std::vector<I> &vu)
192  {
193  using namespace std;
194  if (vu.empty()) return;
195 
196  tsize start=0;
197  int order=-1;
198  T_Healpix_Base<I> base;
199  I offset=0;
200  for (tsize j=0; j<vu.size(); ++j)
201  {
202  int neworder=ilog2(vu[j]>>2)>>1;
203  if (neworder>order)
204  {
205  sort(vu.begin()+start,vu.begin()+j);
206  order=neworder;
207  start=j;
208  base.Set(order,NEST);
209  offset=I(1)<<(2*order+2);
210  }
211  vu[j]=base.peano2nest(vu[j]-offset)+offset;
212  }
213  sort(vu.begin()+start,vu.end());
214  }
215 
216  std::vector<uint8> toCompressed() const
217  {
218  obitstream obs;
219  interpol_encode(rs.data().begin(),rs.data().end(),obs);
220  return obs.state();
221  }
222  static Moc fromCompressed(const std::vector<uint8> &data)
223  {
224  ibitstream ibs(data);
225  std::vector<I> v;
226  interpol_decode(v,ibs);
227  Moc out;
228  out.rs.setData(v);
229  return out;
230  }
231 
232  bool operator==(const Moc &other) const
233  {
234  if (this == &other)
235  return true;
236  return rs==other.rs;
237  }
238 
239  tsize nranges() const
240  { return rs.nranges(); }
241  I nval() const
242  { return rs.nval(); }
243  };
244 
245 #endif
I nest2peano(I pix) const
void Set(int order, Healpix_Ordering_Scheme scheme)
I peano2nest(I pix) const

Generated on Wed Nov 13 2024 12:18:30 for Healpix C++