LSST Applications g0f08755f38+9c285cab97,g1635faa6d4+13f3999e92,g1653933729+a8ce1bb630,g1a0ca8cf93+bf6eb00ceb,g28da252d5a+0829b12dee,g29321ee8c0+5700dc9eac,g2bbee38e9b+9634bc57db,g2bc492864f+9634bc57db,g2cdde0e794+c2c89b37c4,g3156d2b45e+41e33cbcdc,g347aa1857d+9634bc57db,g35bb328faa+a8ce1bb630,g3a166c0a6a+9634bc57db,g3e281a1b8c+9f2c4e2fc3,g414038480c+077ccc18e7,g41af890bb2+fde0dd39b6,g5fbc88fb19+17cd334064,g781aacb6e4+a8ce1bb630,g80478fca09+55a9465950,g82479be7b0+d730eedb7d,g858d7b2824+9c285cab97,g9125e01d80+a8ce1bb630,g9726552aa6+10f999ec6a,ga5288a1d22+2a84bb7594,gacf8899fa4+c69c5206e8,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+9634bc57db,gcf0d15dbbd+4b7d09cae4,gda3e153d99+9c285cab97,gda6a2b7d83+4b7d09cae4,gdaeeff99f8+1711a396fd,ge2409df99d+5e831397f4,ge79ae78c31+9634bc57db,gf0baf85859+147a0692ba,gf3967379c6+41c94011de,gf3fb38a9a8+8f07a9901b,gfb92a5be7c+9c285cab97,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
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 (std::int32_t numStripes, std::int32_t numSubStripesPerStripe)
 
bool operator== (Chunker const &c) const
 
bool operator!= (Chunker const &c) const
 
std::int32_t getNumStripes () const
 getNumStripes returns the number of fixed-height latitude intervals in the sky subdivision.
 
std::int32_t getNumSubStripesPerStripe () const
 getNumSubStripesPerStripe returns the number of fixed-height latitude sub-intervals in each stripe.
 
std::vector< std::int32_tgetChunksIntersecting (Region const &r) const
 getChunksIntersecting returns all the chunks that potentially intersect the given region.
 
std::vector< SubChunksgetSubChunksIntersecting (Region const &r) const
 getSubChunksIntersecting returns all the sub-chunks that potentially intersect the given region.
 
std::vector< std::int32_tgetAllChunks () const
 getAllChunks returns the complete set of chunk IDs for the unit sphere.
 
std::vector< std::int32_tgetAllSubChunks (std::int32_t chunkId) const
 getAllSubChunks returns the complete set of sub-chunk IDs for the given chunk.
 
bool valid (std::int32_t chunkId) const
 Return 'true' if the specified chunk number is valid.
 
Box getChunkBoundingBox (std::int32_t stripe, std::int32_t chunk) const
 
Box getSubChunkBoundingBox (std::int32_t subStripe, std::int32_t subChunk) const
 
std::int32_t getStripe (std::int32_t chunkId) const
 Return the stripe for the specified chunkId.
 
std::int32_t getChunk (std::int32_t chunkId, std::int32_t stripe) const
 Return the chunk for the given chunkId and stripe.
 

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 73 of file Chunker.h.

Constructor & Destructor Documentation

◆ Chunker()

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

Definition at line 64 of file Chunker.cc.

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

Member Function Documentation

◆ getAllChunks()

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

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

Definition at line 265 of file Chunker.cc.

265 {
267 for (std::int32_t s = 0; s < _numStripes; ++s) {
268 std::int32_t nc = _stripes[s].numChunksPerStripe;
269 for (std::int32_t c = 0; c < nc; ++c) {
270 chunkIds.push_back(_getChunkId(s, c));
271 }
272 }
273 return chunkIds;
274}

◆ getAllSubChunks()

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

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

Definition at line 276 of file Chunker.cc.

276 {
277 std::vector<std::int32_t> subChunkIds;
278 std::int32_t s = getStripe(chunkId);
279 subChunkIds.reserve(_stripes.at(s).numSubChunksPerChunk);
280 std::int32_t const ssBeg = s * _numSubStripesPerStripe;
281 std::int32_t const ssEnd = ssBeg + _numSubStripesPerStripe;
282 for (std::int32_t ss = ssBeg; ss < ssEnd; ++ss) {
283 std::int32_t const scEnd = _subStripes[ss].numSubChunksPerChunk;
284 std::int32_t const subChunkIdBase = _maxSubChunksPerSubStripeChunk * (ss - ssBeg);
285 for (std::int32_t sc = 0; sc < scEnd; ++sc) {
286 subChunkIds.push_back(subChunkIdBase + sc);
287 }
288 }
289 return subChunkIds;
290}
T at(T... args)
std::int32_t getStripe(std::int32_t chunkId) const
Return the stripe for the specified chunkId.
Definition Chunker.h:123

◆ getChunk()

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

Return the chunk for the given chunkId and stripe.

Definition at line 128 of file Chunker.h.

128 {
129 return chunkId - stripe*2*_numStripes;
130 }

◆ getChunkBoundingBox()

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

Definition at line 298 of file Chunker.cc.

298 {
299 Angle chunkWidth = _stripes[stripe].chunkWidth;
300 NormalizedAngleInterval lon(chunkWidth * chunk,
301 chunkWidth * (chunk + 1));
302 std::int32_t ss = stripe * _numSubStripesPerStripe;
303 std::int32_t ssEnd = ss + _numSubStripesPerStripe;
304 AngleInterval lat(ss * _subStripeHeight - Angle(0.5 * PI),
305 ssEnd * _subStripeHeight - Angle(0.5 * PI));
306 return Box(lon, lat).dilatedBy(Angle(BOX_EPSILON));
307}

◆ getChunksIntersecting()

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

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

Definition at line 110 of file Chunker.cc.

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

◆ getNumStripes()

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

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

Definition at line 90 of file Chunker.h.

90 {
91 return _numStripes;
92 }

◆ getNumSubStripesPerStripe()

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

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

Definition at line 96 of file Chunker.h.

96 {
97 return _numSubStripesPerStripe;
98 }

◆ getStripe()

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

Return the stripe for the specified chunkId.

Definition at line 123 of file Chunker.h.

123 {
124 return chunkId / (2 * _numStripes);
125 }

◆ getSubChunkBoundingBox()

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

Definition at line 309 of file Chunker.cc.

309 {
310 Angle subChunkWidth = _subStripes[subStripe].subChunkWidth;
311 NormalizedAngleInterval lon(subChunkWidth * subChunk,
312 subChunkWidth * (subChunk + 1));
313 AngleInterval lat(subStripe * _subStripeHeight - Angle(0.5 * PI),
314 (subStripe + 1) * _subStripeHeight - Angle(0.5 * PI));
315 return Box(lon, lat).dilatedBy(Angle(BOX_EPSILON));
316}

◆ 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 155 of file Chunker.cc.

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

◆ operator!=()

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

Definition at line 83 of file Chunker.h.

83 {
84 return _numStripes != c._numStripes ||
85 _numSubStripesPerStripe != c._numSubStripesPerStripe;
86 }

◆ operator==()

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

Definition at line 78 of file Chunker.h.

78 {
79 return _numStripes == c._numStripes &&
80 _numSubStripesPerStripe == c._numSubStripesPerStripe;
81 }

◆ valid()

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

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

Definition at line 292 of file Chunker.cc.

292 {
293 std::int32_t const s = getStripe(chunkId);
294 return s >= 0 and s < _numStripes and
295 getChunk(chunkId, s) < _stripes.at(s).numChunksPerStripe;
296}
std::int32_t getChunk(std::int32_t chunkId, std::int32_t stripe) const
Return the chunk for the given chunkId and stripe.
Definition Chunker.h:128

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