LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Classes | Public Member Functions | List of all members
lsst::sphgeom::Chunker Class Reference

Chunker subdivides the unit sphere into longitude-latitude boxes. More...

#include <Chunker.h>

Public Member Functions

 Chunker (int32_t numStripes, int32_t numSubStripesPerStripe)
 
bool operator== (Chunker const &c) const
 
bool operator!= (Chunker const &c) const
 
int32_t getNumStripes () const
 getNumStripes returns the number of fixed-height latitude intervals in the sky subdivision. More...
 
int32_t getNumSubStripesPerStripe () const
 getNumSubStripesPerStripe returns the number of fixed-height latitude sub-intervals in each stripe. More...
 
std::vector< int32_t > getChunksIntersecting (Region const &r) const
 getChunksIntersecting returns all the chunks that potentially intersect the given region. More...
 
std::vector< SubChunksgetSubChunksIntersecting (Region const &r) const
 getSubChunksIntersecting returns all the sub-chunks that potentially intersect the given region. More...
 
std::vector< int32_t > getAllChunks () const
 getAllChunks returns the complete set of chunk IDs for the unit sphere. More...
 
std::vector< int32_t > getAllSubChunks (int32_t chunkId) const
 getAllSubChunks returns the complete set of sub-chunk IDs for the given chunk. More...
 
bool valid (int32_t chunkId) const
 Return 'true' if the specified chunk number is valid. More...
 
Box getChunkBoundingBox (int32_t stripe, int32_t chunk) const
 
Box getSubChunkBoundingBox (int32_t subStripe, int32_t subChunk) const
 
int32_t getStripe (int32_t chunkId) const
 Return the stripe for the specified chunkId. More...
 
int32_t getChunk (int32_t chunkId, int32_t stripe) const
 Return the chunk for the given chunkId and stripe. More...
 

Detailed Description

Chunker subdivides the unit sphere into longitude-latitude boxes.

The unit sphere is divided into latitude angle "stripes" of fixed height H. For each stripe, a width W is computed such that any two points in the stripe with longitude angles separated by at least W have angular separation of at least H. The stripe is then broken into an integral number of chunks of width at least W. The same procedure is used to obtain finer subchunks - each stripe is broken into a configureable number of equal-height "substripes", and each substripe is broken into equal-width subchunks.

Definition at line 66 of file Chunker.h.

Constructor & Destructor Documentation

◆ Chunker()

lsst::sphgeom::Chunker::Chunker ( int32_t  numStripes,
int32_t  numSubStripesPerStripe 
)

Definition at line 57 of file Chunker.cc.

58  :
59  _numStripes(numStripes),
60  _numSubStripesPerStripe(numSubStripesPerStripe),
61  _numSubStripes(numStripes * numSubStripesPerStripe),
62  _maxSubChunksPerSubStripeChunk(0),
63  _subStripeHeight(Angle(PI) / _numSubStripes)
64 {
65  if (numStripes < 1 || numSubStripesPerStripe < 1) {
66  throw std::runtime_error("The number of stripes and sub-stripes "
67  "per stripe must be positive");
68  }
69  if (numStripes * numSubStripesPerStripe > 180*3600) {
70  throw std::runtime_error("Sub-stripes are too small");
71  }
72  Angle const stripeHeight = Angle(PI) / _numStripes;
73  _stripes.reserve(_numStripes);
74  _subStripes.reserve(_numSubStripes);
75  for (int32_t s = 0; s < _numStripes; ++s) {
76  // Compute stripe latitude bounds.
77  AngleInterval sLat(s * stripeHeight - Angle(0.5 * PI),
78  (s + 1) * stripeHeight - Angle(0.5 * PI));
79  Stripe stripe;
80  int32_t const nc = computeNumSegments(sLat, stripeHeight);
81  stripe.chunkWidth = Angle(2.0 * PI) / nc;
82  stripe.numChunksPerStripe = nc;
83  int32_t ss = s * _numSubStripesPerStripe;
84  int32_t const ssEnd = ss + _numSubStripesPerStripe;
85  for (; ss < ssEnd; ++ss) {
86  // Compute sub-stripe latitude bounds.
87  AngleInterval ssLat(ss * _subStripeHeight - Angle(0.5 * PI),
88  (ss + 1) * _subStripeHeight - Angle(0.5 * PI));
89  SubStripe subStripe;
90  int32_t const nsc = computeNumSegments(ssLat, _subStripeHeight) / nc;
91  stripe.numSubChunksPerChunk += nsc;
92  subStripe.numSubChunksPerChunk = nsc;
93  if (nsc > _maxSubChunksPerSubStripeChunk) {
94  _maxSubChunksPerSubStripeChunk = nsc;
95  }
96  subStripe.subChunkWidth = Angle(2.0 * PI) / (nsc * nc);
97  _subStripes.push_back(subStripe);
98  }
99  _stripes.push_back(stripe);
100  }
101 }
lsst::geom::Angle Angle
Definition: misc.h:33
constexpr double PI
Definition: constants.h:36
T push_back(T... args)
T reserve(T... args)

Member Function Documentation

◆ getAllChunks()

std::vector< int32_t > lsst::sphgeom::Chunker::getAllChunks ( ) const

getAllChunks returns the complete set of chunk IDs for the unit sphere.

Definition at line 258 of file Chunker.cc.

258  {
259  std::vector<int32_t> chunkIds;
260  for (int32_t s = 0; s < _numStripes; ++s) {
261  int32_t nc = _stripes[s].numChunksPerStripe;
262  for (int32_t c = 0; c < nc; ++c) {
263  chunkIds.push_back(_getChunkId(s, c));
264  }
265  }
266  return chunkIds;
267 }

◆ getAllSubChunks()

std::vector< int32_t > lsst::sphgeom::Chunker::getAllSubChunks ( int32_t  chunkId) const

getAllSubChunks returns the complete set of sub-chunk IDs for the given chunk.

Definition at line 269 of file Chunker.cc.

269  {
270  std::vector<int32_t> subChunkIds;
271  int32_t s = getStripe(chunkId);
272  subChunkIds.reserve(_stripes.at(s).numSubChunksPerChunk);
273  int32_t const ssBeg = s * _numSubStripesPerStripe;
274  int32_t const ssEnd = ssBeg + _numSubStripesPerStripe;
275  for (int32_t ss = ssBeg; ss < ssEnd; ++ss) {
276  int32_t const scEnd = _subStripes[ss].numSubChunksPerChunk;
277  int32_t const subChunkIdBase = _maxSubChunksPerSubStripeChunk * (ss - ssBeg);
278  for (int32_t sc = 0; sc < scEnd; ++sc) {
279  subChunkIds.push_back(subChunkIdBase + sc);
280  }
281  }
282  return subChunkIds;
283 }
T at(T... args)
int32_t getStripe(int32_t chunkId) const
Return the stripe for the specified chunkId.
Definition: Chunker.h:116

◆ getChunk()

int32_t lsst::sphgeom::Chunker::getChunk ( int32_t  chunkId,
int32_t  stripe 
) const
inline

Return the chunk for the given chunkId and stripe.

Definition at line 121 of file Chunker.h.

121  {
122  return chunkId - stripe*2*_numStripes;
123  }

◆ getChunkBoundingBox()

Box lsst::sphgeom::Chunker::getChunkBoundingBox ( int32_t  stripe,
int32_t  chunk 
) const

Definition at line 291 of file Chunker.cc.

291  {
292  Angle chunkWidth = _stripes[stripe].chunkWidth;
293  NormalizedAngleInterval lon(chunkWidth * chunk,
294  chunkWidth * (chunk + 1));
295  int32_t ss = stripe * _numSubStripesPerStripe;
296  int32_t ssEnd = ss + _numSubStripesPerStripe;
297  AngleInterval lat(ss * _subStripeHeight - Angle(0.5 * PI),
298  ssEnd * _subStripeHeight - Angle(0.5 * PI));
299  return Box(lon, lat).dilatedBy(Angle(BOX_EPSILON));
300 }

◆ getChunksIntersecting()

std::vector< int32_t > lsst::sphgeom::Chunker::getChunksIntersecting ( Region const &  r) const

getChunksIntersecting returns all the chunks that potentially intersect the given region.

Definition at line 103 of file Chunker.cc.

103  {
104  std::vector<int32_t> chunkIds;
105  // Find the stripes that intersect the bounding box of r.
106  Box b = r.getBoundingBox().dilatedBy(Angle(BOX_EPSILON));
107  double ya = std::floor((b.getLat().getA() + Angle(0.5 * PI)) / _subStripeHeight);
108  double yb = std::floor((b.getLat().getB() + Angle(0.5 * PI)) / _subStripeHeight);
109  int32_t minSS = std::min(static_cast<int32_t>(ya), _numSubStripes - 1);
110  int32_t maxSS = std::min(static_cast<int32_t>(yb), _numSubStripes - 1);
111  int32_t minS = minSS / _numSubStripesPerStripe;
112  int32_t maxS = maxSS / _numSubStripesPerStripe;
113  for (int32_t s = minS; s <= maxS; ++s) {
114  // Find the chunks of s that intersect the bounding box of r.
115  Angle chunkWidth = _stripes[s].chunkWidth;
116  int32_t nc = _stripes[s].numChunksPerStripe;
117  double xa = std::floor(b.getLon().getA() / chunkWidth);
118  double xb = std::floor(b.getLon().getB() / chunkWidth);
119  int32_t ca = std::min(static_cast<int32_t>(xa), nc - 1);
120  int32_t cb = std::min(static_cast<int32_t>(xb), nc - 1);
121  if (ca == cb && b.getLon().wraps()) {
122  ca = 0;
123  cb = nc - 1;
124  }
125  // Examine each chunk overlapping the bounding box of r.
126  if (ca <= cb) {
127  for (int32_t c = ca; c <= cb; ++c) {
128  if ((r.relate(getChunkBoundingBox(s, c)) & DISJOINT) == 0) {
129  chunkIds.push_back(_getChunkId(s, c));
130  }
131  }
132  } else {
133  for (int32_t c = 0; c <= cb; ++c) {
134  if ((r.relate(getChunkBoundingBox(s, c)) & DISJOINT) == 0) {
135  chunkIds.push_back(_getChunkId(s, c));
136  }
137  }
138  for (int32_t c = ca; c < nc; ++c) {
139  if ((r.relate(getChunkBoundingBox(s, c)) & DISJOINT) == 0) {
140  chunkIds.push_back(_getChunkId(s, c));
141  }
142  }
143  }
144  }
145  return chunkIds;
146 }
table::Key< int > b
Box getChunkBoundingBox(int32_t stripe, int32_t chunk) const
Definition: Chunker.cc:291
T floor(T... args)
T min(T... args)

◆ getNumStripes()

int32_t lsst::sphgeom::Chunker::getNumStripes ( ) const
inline

getNumStripes returns the number of fixed-height latitude intervals in the sky subdivision.

Definition at line 83 of file Chunker.h.

83  {
84  return _numStripes;
85  }

◆ getNumSubStripesPerStripe()

int32_t lsst::sphgeom::Chunker::getNumSubStripesPerStripe ( ) const
inline

getNumSubStripesPerStripe returns the number of fixed-height latitude sub-intervals in each stripe.

Definition at line 89 of file Chunker.h.

89  {
90  return _numSubStripesPerStripe;
91  }

◆ getStripe()

int32_t lsst::sphgeom::Chunker::getStripe ( int32_t  chunkId) const
inline

Return the stripe for the specified chunkId.

Definition at line 116 of file Chunker.h.

116  {
117  return chunkId / (2 * _numStripes);
118  }

◆ getSubChunkBoundingBox()

Box lsst::sphgeom::Chunker::getSubChunkBoundingBox ( int32_t  subStripe,
int32_t  subChunk 
) const

Definition at line 302 of file Chunker.cc.

302  {
303  Angle subChunkWidth = _subStripes[subStripe].subChunkWidth;
304  NormalizedAngleInterval lon(subChunkWidth * subChunk,
305  subChunkWidth * (subChunk + 1));
306  AngleInterval lat(subStripe * _subStripeHeight - Angle(0.5 * PI),
307  (subStripe + 1) * _subStripeHeight - Angle(0.5 * PI));
308  return Box(lon, lat).dilatedBy(Angle(BOX_EPSILON));
309 }

◆ getSubChunksIntersecting()

std::vector< SubChunks > lsst::sphgeom::Chunker::getSubChunksIntersecting ( Region const &  r) const

getSubChunksIntersecting returns all the sub-chunks that potentially intersect the given region.

Definition at line 148 of file Chunker.cc.

150 {
151  std::vector<SubChunks> chunks;
152  // Find the stripes that intersect the bounding box of r.
153  Box b = r.getBoundingBox().dilatedBy(Angle(BOX_EPSILON));
154  double ya = std::floor((b.getLat().getA() + Angle(0.5 * PI)) / _subStripeHeight);
155  double yb = std::floor((b.getLat().getB() + Angle(0.5 * PI)) / _subStripeHeight);
156  int32_t minSS = std::min(static_cast<int32_t>(ya), _numSubStripes - 1);
157  int32_t maxSS = std::min(static_cast<int32_t>(yb), _numSubStripes - 1);
158  int32_t minS = minSS / _numSubStripesPerStripe;
159  int32_t maxS = maxSS / _numSubStripesPerStripe;
160  for (int32_t s = minS; s <= maxS; ++s) {
161  // Find the chunks of s that intersect the bounding box of r.
162  Angle chunkWidth = _stripes[s].chunkWidth;
163  int32_t nc = _stripes[s].numChunksPerStripe;
164  double xa = std::floor(b.getLon().getA() / chunkWidth);
165  double xb = std::floor(b.getLon().getB() / chunkWidth);
166  int32_t ca = std::min(static_cast<int32_t>(xa), nc - 1);
167  int32_t cb = std::min(static_cast<int32_t>(xb), nc - 1);
168  if (ca == cb && b.getLon().wraps()) {
169  ca = 0;
170  cb = nc - 1;
171  }
172  // Examine sub-chunks for each chunk overlapping the bounding box of r.
173  if (ca <= cb) {
174  for (int32_t c = ca; c <= cb; ++c) {
175  _getSubChunks(chunks, r, b.getLon(), s, c, minSS, maxSS);
176  }
177  } else {
178  for (int32_t c = 0; c <= cb; ++c) {
179  _getSubChunks(chunks, r, b.getLon(), s, c, minSS, maxSS);
180  }
181  for (int32_t c = ca; c < nc; ++c) {
182  _getSubChunks(chunks, r, b.getLon(), s, c, minSS, maxSS);
183  }
184  }
185  }
186  return chunks;
187 }

◆ operator!=()

bool lsst::sphgeom::Chunker::operator!= ( Chunker const &  c) const
inline

Definition at line 76 of file Chunker.h.

76  {
77  return _numStripes != c._numStripes ||
78  _numSubStripesPerStripe != c._numSubStripesPerStripe;
79  }

◆ operator==()

bool lsst::sphgeom::Chunker::operator== ( Chunker const &  c) const
inline

Definition at line 71 of file Chunker.h.

71  {
72  return _numStripes == c._numStripes &&
73  _numSubStripesPerStripe == c._numSubStripesPerStripe;
74  }

◆ valid()

bool lsst::sphgeom::Chunker::valid ( int32_t  chunkId) const

Return 'true' if the specified chunk number is valid.

Definition at line 285 of file Chunker.cc.

285  {
286  int32_t const s = getStripe(chunkId);
287  return s >= 0 and s < _numStripes and
288  getChunk(chunkId, s) < _stripes.at(s).numChunksPerStripe;
289 }
int32_t getChunk(int32_t chunkId, int32_t stripe) const
Return the chunk for the given chunkId and stripe.
Definition: Chunker.h:121

The documentation for this class was generated from the following files: