LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
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

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}
T push_back(T... args)

◆ 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}
int32_t getStripe(int32_t chunkId) const
Return the stripe for the specified chunkId.
Definition: Chunker.h:116
T reserve(T... args)

◆ 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{
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: