use crate::{Gain, IntegrationTime};
#[cfg(feature = "lux_as_f32")]
use micromath::F32Ext;
pub fn calculate_raw_threshold_value(it: IntegrationTime, gain: Gain, lux: f32) -> u16 {
let factor = get_lux_raw_conversion_factor(it, gain);
if (gain == Gain::OneQuarter || gain == Gain::OneEighth) && lux > 1000.0 {
let lux = inverse_high_lux_correction(lux);
(lux / factor) as u16
} else {
(lux / factor) as u16
}
}
pub(crate) fn get_lux_raw_conversion_factor(it: IntegrationTime, gain: Gain) -> f32 {
let gain_factor = match gain {
Gain::Two => 1.0,
Gain::One => 2.0,
Gain::OneQuarter => 8.0,
Gain::OneEighth => 16.0,
};
let it_factor = match it {
IntegrationTime::_800ms => 0.0042,
IntegrationTime::_400ms => 0.0084,
IntegrationTime::_200ms => 0.0168,
IntegrationTime::_100ms => 0.0336,
IntegrationTime::_50ms => 0.0672,
IntegrationTime::_25ms => 0.1344,
};
gain_factor * it_factor
}
const C0: f32 = 1.0023;
const C1: f32 = 8.1488e-05;
const C2: f32 = -9.3924e-09;
const C3: f32 = 6.0135e-13;
pub(crate) fn correct_high_lux(lux: f32) -> f32 {
lux.powf(4.0) * C3 + lux.powf(3.0) * C2 + lux * lux * C1 + lux * C0
}
fn inverse_high_lux_correction(lux: f32) -> f32 {
-C2 / (4.0 * C3)
- (C2.powf(2.0) / (4.0 * C3.powf(2.0)) - (2.0 * C1) / (3.0 * C3)
+ (2.0_f32.powf(1.0 / 3.0) * (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux))
/ (3.0
* C3
* (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0 + 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux
+ (-4.0 * (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux).powf(3.0)
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0
+ 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux)
.powf(2.0))
.sqrt())
.powf(1.0 / 3.0))
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0 + 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux
+ (-4.0 * (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux).powf(3.0)
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0 + 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux)
.powf(2.0))
.sqrt())
.powf(1.0 / 3.0)
/ (3.0 * 2.0_f32.powf(1.0 / 3.0) * C3))
.sqrt()
/ 2.0
+ (C2.powf(2.0) / (2.0 * C3.powf(2.0))
- (4.0 * C1) / (3.0 * C3)
- (2.0_f32.powf(1.0 / 3.0) * (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux))
/ (3.0
* C3
* (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0 + 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux
+ (-4.0 * (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux).powf(3.0)
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0
+ 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux)
.powf(2.0))
.sqrt())
.powf(1.0 / 3.0))
- (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0 + 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux
+ (-4.0 * (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux).powf(3.0)
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0 + 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux)
.powf(2.0))
.sqrt())
.powf(1.0 / 3.0)
/ (3.0 * 2.0_f32.powf(1.0 / 3.0) * C3)
- (-(C2.powf(3.0) / C3.powf(3.0)) + (4.0 * C2 * C1) / C3.powf(2.0) - (8.0 * C0) / C3)
/ (4.0
* (C2.powf(2.0) / (4.0 * C3.powf(2.0)) - (2.0 * C1) / (3.0 * C3)
+ (2.0_f32.powf(1.0 / 3.0)
* (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux))
/ (3.0
* C3
* (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0
+ 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux
+ (-4.0
* (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux)
.powf(3.0)
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0
+ 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux)
.powf(2.0))
.sqrt())
.powf(1.0 / 3.0))
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0 + 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux
+ (-4.0
* (C1.powf(2.0) - 3.0 * C2 * C0 - 12.0 * C3 * lux).powf(3.0)
+ (2.0 * C1.powf(3.0) - 9.0 * C2 * C1 * C0
+ 27.0 * C3 * C0.powf(2.0)
- 27.0 * C2.powf(2.0) * lux
+ 72.0 * C3 * C1 * lux)
.powf(2.0))
.sqrt())
.powf(1.0 / 3.0)
/ (3.0 * 2.0_f32.powf(1.0 / 3.0) * C3))
.sqrt()))
.sqrt()
/ 2.0
}