FireSTARR
Loading...
Searching...
No Matches
Cell.h
1/* Copyright (c) Queen's Printer for Ontario, 2020. */
2/* Copyright (c) His Majesty the King in Right of Canada as represented by the Minister of Natural Resources, 2025. */
3
4/* SPDX-License-Identifier: AGPL-3.0-or-later */
5
6#pragma once
7#include <limits>
8#include "Location.h"
9#include "FuelType.h"
10#include "Util.h"
11namespace fs::topo
12{
13using SpreadKey = uint32_t;
14using fuel::INVALID_FUEL_CODE;
18class Cell
19 : public Position<Topo>
20{
21public:
25 constexpr Cell() noexcept
26 : Cell(-1,
27 -1,
28 numeric_limits<SlopeSize>::min(),
29 numeric_limits<AspectSize>::min(),
30 numeric_limits<FuelCodeSize>::min())
31 {
32 }
37 [[nodiscard]] constexpr Topo fullHash() const
38 {
39 return topo_data_;
40 }
48 [[nodiscard]] static constexpr Topo hashCell(const SlopeSize slope,
49 const AspectSize aspect,
50 const FuelCodeSize& fuel) noexcept
51 {
52 // HACK: so we can call and set it all invalid if anything is
53 // if any are invalid then they all should be
54 const auto do_hash_cell = [](const SlopeSize s, const AspectSize a, const FuelCodeSize f) {
55 return static_cast<Topo>(f) << FuelShift
56 | static_cast<Topo>(s) << SlopeShift
57 | static_cast<Topo>(a) << AspectShift;
58 };
59 if (
60 INVALID_SLOPE == slope
61 || INVALID_ASPECT == aspect
62 || INVALID_FUEL_CODE == fuel)
63 {
64 return do_hash_cell(INVALID_SLOPE, INVALID_ASPECT, INVALID_FUEL_CODE);
65 }
66 // if slope is 0 make aspect north so less unique keys
67 return do_hash_cell(slope, 0 == slope ? 0 : aspect, fuel);
68 }
73 explicit constexpr Cell(const Topo hash) noexcept
74 : Position<Topo>(hash)
75 {
76 }
84 constexpr Cell(const HashSize hash,
85 const SlopeSize slope,
86 const AspectSize aspect,
87 const FuelCodeSize& fuel) noexcept
89 static_cast<Topo>(hash & HashMask)
90 | hashCell(slope, aspect, fuel))
91 {
92 }
101 constexpr Cell(const Idx row,
102 const Idx column,
103 const SlopeSize slope,
104 const AspectSize aspect,
105 const FuelCodeSize& fuel) noexcept
107 static_cast<Topo>(doHash(row, column))
108 | hashCell(slope, aspect, fuel))
109 {
110 }
116 [[nodiscard]] static constexpr SpreadKey key(const Topo value) noexcept
117 {
118 // can just shift since these are the only bits left after
119 return static_cast<SpreadKey>(value >> FuelShift);
120 }
126 [[nodiscard]] static constexpr AspectSize aspect(const SpreadKey value) noexcept
127 {
128 return static_cast<AspectSize>((value & (AspectMask >> FuelShift)) >> (AspectShift - FuelShift));
129 }
136 [[nodiscard]] static constexpr FuelCodeSize fuelCode(const SpreadKey value) noexcept
137 {
138 return static_cast<FuelCodeSize>((value & (FuelMask >> FuelShift)) >> (FuelShift - FuelShift));
139 }
145 [[nodiscard]] static constexpr SlopeSize slope(const SpreadKey value) noexcept
146 {
147 return static_cast<SlopeSize>((value & (SlopeMask >> FuelShift)) >> (SlopeShift - FuelShift));
148 }
154 [[nodiscard]] static constexpr AspectSize aspect(const Topo value) noexcept
155 {
156 return static_cast<AspectSize>((value & AspectMask) >> AspectShift);
157 }
164 [[nodiscard]] static constexpr FuelCodeSize fuelCode(const Topo value) noexcept
165 {
166 return static_cast<FuelCodeSize>((value & FuelMask) >> FuelShift);
167 }
173 [[nodiscard]] static constexpr SlopeSize slope(const Topo value) noexcept
174 {
175 return static_cast<SlopeSize>((value & SlopeMask) >> SlopeShift);
176 }
182 [[nodiscard]] static constexpr Topo topoHash(const Topo value) noexcept
183 {
184 return static_cast<Topo>(value) & CellMask;
185 }
190 [[nodiscard]] constexpr SpreadKey key() const noexcept
191 {
192 return Cell::key(topo_data_);
193 }
198 [[nodiscard]] constexpr AspectSize aspect() const noexcept
199 {
200 return Cell::aspect(topo_data_);
201 }
206 [[nodiscard]] constexpr FuelCodeSize fuelCode() const noexcept
207 {
209 }
214 [[nodiscard]] constexpr SlopeSize slope() const noexcept
215 {
216 return Cell::slope(topo_data_);
217 }
222 [[nodiscard]] constexpr Topo topoHash() const noexcept
223 {
225 }
226protected:
227 /*
228 * Field Natural Range Used Range Bits Bit Range
229 * Row 0 - 4095 0 - 4095 12 0 - 4095
230 * Column 0 - 4095 0 - 4095 12 0 - 4095
231 * PADDING 10
232 * Fuel 0 - 140 0 - 140 8 0 - 255
233 * Aspect 0 - 359 0 - 359 9 0 - 511
234<<<<<<< HEAD
235 * Slope 0 - infinity 0 - 511 9 0 - 511
236=======
237 * Slope 0 - infinity 0 - 127 7 0 - 127
238>>>>>>> 70c2f12ad (quick fix for seasonal/specific mixedwood fuels)
239 * Extra 8
240 *
241 * Rows and Columns are restricted to 4096 since that's what gets clipped out of
242 * the GIS outputs.
243 *
244 * Fuel is tied to how many variations of percent conifer/dead fir we want to use, and
245 * if we want to allow M1/M2/M3/M4 on their own, or just use the ones that are
246 * automatically tied to the green-up.
247 *
248 * Aspect is calculated to be in degrees, so 0 - 359.
249 *
250 * Slope is truncated to 0 - 70 for slope effect calculations speed for slopes,
251 * but keep higher range because there's an issue with this when it tries to calculate the
252 * horizontal rate of spread since if the slope has been truncated and the distance
253 * calculated will be wrong.
254 */
258 static constexpr uint32_t FuelShift = 32;
259 // Need to make sure that fuel, slope & aspect aren't in first 32 bits
260 static_assert(32 <= FuelShift);
264 static constexpr uint32_t FuelBits = std::bit_width<uint32_t>(NUMBER_OF_FUELS);
268 static constexpr Topo FuelBitMask = util::bit_mask<FuelBits, Topo>();
269 static_assert(FuelBitMask == 0xFF);
270 static_assert(FuelBitMask >= NUMBER_OF_FUELS);
274 static constexpr Topo FuelMask = FuelBitMask << FuelShift;
278 static constexpr uint32_t AspectShift = FuelBits + FuelShift;
282 static constexpr uint32_t AspectBits = std::bit_width<uint32_t>(MAX_ASPECT);
286 static constexpr Topo AspectBitMask = util::bit_mask<AspectBits, Topo>();
287 static_assert(AspectBitMask == 0x1FF);
288 static_assert(AspectBitMask >= INVALID_ASPECT);
292 static constexpr Topo AspectMask = AspectBitMask << AspectShift;
296 static constexpr uint32_t SlopeShift = AspectBits + AspectShift;
300 static constexpr uint32_t SlopeBits = std::bit_width<uint32_t>(MAX_SLOPE_FOR_DISTANCE);
301 static_assert(SlopeBits == 9);
305 static constexpr Topo SlopeBitMask = util::bit_mask<SlopeBits, Topo>();
306 static_assert(SlopeBitMask == 0x1FF);
307 static_assert(SlopeBitMask >= INVALID_SLOPE);
311 static constexpr Topo SlopeMask = SlopeBitMask << SlopeShift;
315 static constexpr Topo CellMask = HashMask | FuelMask | AspectMask | SlopeMask;
316 static_assert(static_cast<size_t>(std::bit_width(std::numeric_limits<Topo>::max())) >= SlopeBits + SlopeShift);
317};
324constexpr bool operator<(const Cell& lhs, const Cell& rhs)
325{
326 return lhs.topoHash() < rhs.topoHash();
327}
328}
329namespace std
330{
334template <>
335struct hash<fs::topo::Cell>
336{
342 std::size_t operator()(const fs::topo::Cell& k) const noexcept
343 {
344 return k.fullHash();
345 }
346};
347}
A Position with a Slope, Aspect, and Fuel.
Definition Cell.h:20
static constexpr Topo CellMask
Bitmask for Cell information in Topo.
Definition Cell.h:315
static constexpr AspectSize aspect(const Topo value) noexcept
Aspect (degrees)
Definition Cell.h:154
static constexpr uint32_t SlopeShift
Shift for slope bitmask.
Definition Cell.h:296
constexpr Cell(const HashSize hash, const SlopeSize slope, const AspectSize aspect, const FuelCodeSize &fuel) noexcept
Construct based on given attributes.
Definition Cell.h:84
constexpr Cell(const Topo hash) noexcept
Construct from hash value.
Definition Cell.h:73
constexpr AspectSize aspect() const noexcept
Aspect (degrees)
Definition Cell.h:198
static constexpr AspectSize aspect(const SpreadKey value) noexcept
Aspect (degrees)
Definition Cell.h:126
static constexpr Topo SlopeMask
Bitmask for slope in Topo.
Definition Cell.h:311
static constexpr Topo hashCell(const SlopeSize slope, const AspectSize aspect, const FuelCodeSize &fuel) noexcept
Hash attributes into a Topo value.
Definition Cell.h:48
static constexpr Topo SlopeBitMask
Bitmask for slope in Topo before shift.
Definition Cell.h:305
static constexpr SpreadKey key(const Topo value) noexcept
A key defining Slope, Aspect, and Fuel, used for determining Cells that spread the same.
Definition Cell.h:116
static constexpr uint32_t SlopeBits
Number of bits in slope bitmask.
Definition Cell.h:300
constexpr SpreadKey key() const noexcept
A key defining Slope, Aspect, and Fuel, used for determining Cells that spread the same.
Definition Cell.h:190
constexpr SlopeSize slope() const noexcept
Slope (degrees)
Definition Cell.h:214
static constexpr uint32_t FuelBits
Number of bits in fuel bitmask.
Definition Cell.h:264
static constexpr Topo topoHash(const Topo value) noexcept
Topo that contains Cell data.
Definition Cell.h:182
static constexpr Topo AspectBitMask
Bitmask for aspect in Topo before shift.
Definition Cell.h:286
constexpr Topo topoHash() const noexcept
Topo that contains Cell data.
Definition Cell.h:222
static constexpr uint32_t AspectBits
Number of bits in aspect bitmask.
Definition Cell.h:282
static constexpr SlopeSize slope(const Topo value) noexcept
Slope (degrees)
Definition Cell.h:173
constexpr Cell(const Idx row, const Idx column, const SlopeSize slope, const AspectSize aspect, const FuelCodeSize &fuel) noexcept
Constructor.
Definition Cell.h:101
static constexpr FuelCodeSize fuelCode(const Topo value) noexcept
Fuel.
Definition Cell.h:164
static constexpr FuelCodeSize fuelCode(const SpreadKey value) noexcept
Fuel.
Definition Cell.h:136
static constexpr Topo FuelMask
Bitmask for fuel information in Topo.
Definition Cell.h:274
constexpr FuelCodeSize fuelCode() const noexcept
Fuel.
Definition Cell.h:206
static constexpr Topo AspectMask
Bitmask for aspect in Topo.
Definition Cell.h:292
static constexpr Topo FuelBitMask
Bitmask for fuel information in Topo before shift.
Definition Cell.h:268
static constexpr uint32_t AspectShift
Shift for aspect bitmask.
Definition Cell.h:278
static constexpr SlopeSize slope(const SpreadKey value) noexcept
Slope (degrees)
Definition Cell.h:145
constexpr Topo fullHash() const
Full stored hash that may contain data from subclasses.
Definition Cell.h:37
static constexpr uint32_t FuelShift
Shift for fuel bitmask.
Definition Cell.h:258
constexpr Cell() noexcept
Default constructor.
Definition Cell.h:25
A Position with a row and column.
Definition Location.h:57
static constexpr Topo HashMask
Definition Location.h:133
Topo topo_data_
Definition Location.h:115
constexpr Idx column() const noexcept
Definition Location.h:72
static constexpr HashSize doHash(const Idx row, const Idx column) noexcept
Definition Location.h:150
Definition util.h:14
std::size_t operator()(const fs::topo::Cell &k) const noexcept
Provides hash for Cell objects.
Definition Cell.h:342