Coverage for phenomena/rayleigh.py: 64%

114 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1""" 

2Rayleigh Optical Depth - Scattering in the Atmosphere 

3===================================================== 

4 

5Implement *Rayleigh* scattering and optical depth computation in the 

6atmosphere. 

7 

8- :func:`colour.scattering_cross_section` 

9- :func:`colour.phenomena.rayleigh_optical_depth` 

10- :func:`colour.rayleigh_scattering` 

11 

12References 

13---------- 

14- :cite:`Bodhaine1999a` : Bodhaine, B. A., Wood, N. B., Dutton, E. G., & 

15 Slusser, J. R. (1999). On Rayleigh Optical Depth Calculations. Journal of 

16 Atmospheric and Oceanic Technology, 16(11), 1854-1861. 

17 doi:10.1175/1520-0426(1999)016<1854:ORODC>2.0.CO;2 

18- :cite:`Wikipedia2001c` : Wikipedia. (2001). Rayleigh scattering. Retrieved 

19 September 23, 2014, from http://en.wikipedia.org/wiki/Rayleigh_scattering 

20""" 

21 

22from __future__ import annotations 

23 

24import typing 

25 

26import numpy as np 

27 

28from colour.algebra import sdiv, sdiv_mode 

29from colour.colorimetry import ( 

30 SPECTRAL_SHAPE_DEFAULT, 

31 SpectralDistribution, 

32 SpectralShape, 

33) 

34from colour.constants import CONSTANT_AVOGADRO 

35 

36if typing.TYPE_CHECKING: 

37 from colour.hints import ArrayLike, Callable, NDArrayFloat 

38 

39from colour.utilities import as_float, as_float_array, filter_kwargs 

40 

41__author__ = "Colour Developers" 

42__copyright__ = "Copyright 2013 Colour Developers" 

43__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" 

44__maintainer__ = "Colour Developers" 

45__email__ = "colour-developers@colour-science.org" 

46__status__ = "Production" 

47 

48__all__ = [ 

49 "CONSTANT_STANDARD_AIR_TEMPERATURE", 

50 "CONSTANT_STANDARD_CO2_CONCENTRATION", 

51 "CONSTANT_AVERAGE_PRESSURE_MEAN_SEA_LEVEL", 

52 "CONSTANT_DEFAULT_LATITUDE", 

53 "CONSTANT_DEFAULT_ALTITUDE", 

54 "air_refraction_index_Penndorf1957", 

55 "air_refraction_index_Edlen1966", 

56 "air_refraction_index_Peck1972", 

57 "air_refraction_index_Bodhaine1999", 

58 "N2_depolarisation", 

59 "O2_depolarisation", 

60 "F_air_Penndorf1957", 

61 "F_air_Young1981", 

62 "F_air_Bates1984", 

63 "F_air_Bodhaine1999", 

64 "molecular_density", 

65 "mean_molecular_weights", 

66 "gravity_List1968", 

67 "scattering_cross_section", 

68 "rayleigh_optical_depth", 

69 "rayleigh_scattering", 

70 "sd_rayleigh_scattering", 

71] 

72 

73CONSTANT_STANDARD_AIR_TEMPERATURE: float = 288.15 

74"""*Standard air* temperature :math:`T[K]` in kelvin degrees (:math:`15\\circ C`).""" 

75 

76CONSTANT_STANDARD_CO2_CONCENTRATION: float = 300 

77"""*Standard air* :math:`CO_2` concentration in parts per million (ppm).""" 

78 

79CONSTANT_AVERAGE_PRESSURE_MEAN_SEA_LEVEL: float = 101325 

80"""*Standard air* average pressure :math:`Hg` at mean sea-level in pascal (Pa).""" 

81 

82CONSTANT_DEFAULT_LATITUDE: float = 0 

83"""Default latitude in degrees (equator).""" 

84 

85CONSTANT_DEFAULT_ALTITUDE: float = 0 

86"""Default altitude in meters (sea level).""" 

87 

88 

89def air_refraction_index_Penndorf1957( 

90 wavelength: ArrayLike, 

91) -> NDArrayFloat: 

92 """ 

93 Compute the air refraction index :math:`n_s` from the specified wavelength 

94 :math:`\\lambda` in micrometers (:math:`\\mu m`) using the 

95 *Penndorf (1957)* method. 

96 

97 Parameters 

98 ---------- 

99 wavelength 

100 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

101 

102 Returns 

103 ------- 

104 :class:`numpy.ndarray` 

105 Air refraction index :math:`n_s`. 

106 

107 Examples 

108 -------- 

109 >>> air_refraction_index_Penndorf1957(0.555) # doctest: +ELLIPSIS 

110 1.0002777... 

111 """ 

112 

113 wl = as_float_array(wavelength) 

114 

115 n = 6432.8 + 2949810 / (146 - wl ** (-2)) + 25540 / (41 - wl ** (-2)) 

116 n /= 1.0e8 

117 n += +1 

118 

119 return n 

120 

121 

122def air_refraction_index_Edlen1966( 

123 wavelength: ArrayLike, 

124) -> NDArrayFloat: 

125 """ 

126 Compute the air refraction index :math:`n_s` from the specified wavelength 

127 :math:`\\lambda` in micrometers (:math:`\\mu m`) using the 

128 *Edlen (1966)* method. 

129 

130 Parameters 

131 ---------- 

132 wavelength 

133 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

134 

135 Returns 

136 ------- 

137 :class:`numpy.ndarray` 

138 Air refraction index :math:`n_s`. 

139 

140 Examples 

141 -------- 

142 >>> air_refraction_index_Edlen1966(0.555) # doctest: +ELLIPSIS 

143 1.0002777... 

144 """ 

145 

146 wl = as_float_array(wavelength) 

147 

148 n = 8342.13 + 2406030 / (130 - wl ** (-2)) + 15997 / (38.9 - wl ** (-2)) 

149 n /= 1.0e8 

150 n += +1 

151 

152 return n 

153 

154 

155def air_refraction_index_Peck1972( 

156 wavelength: ArrayLike, 

157) -> NDArrayFloat: 

158 """ 

159 Compute the air refraction index :math:`n_s` from the specified wavelength 

160 :math:`\\lambda` in micrometers (:math:`\\mu m`) using the 

161 *Peck and Reeder (1972)* method. 

162 

163 Parameters 

164 ---------- 

165 wavelength 

166 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

167 

168 Returns 

169 ------- 

170 :class:`numpy.ndarray` 

171 Air refraction index :math:`n_s`. 

172 

173 Examples 

174 -------- 

175 >>> air_refraction_index_Peck1972(0.555) # doctest: +ELLIPSIS 

176 1.0002777... 

177 """ 

178 

179 wl = as_float_array(wavelength) 

180 

181 n = 8060.51 + 2480990 / (132.274 - wl ** (-2)) + 17455.7 / (39.32957 - wl ** (-2)) 

182 n /= 1.0e8 

183 n += +1 

184 

185 return n 

186 

187 

188def air_refraction_index_Bodhaine1999( 

189 wavelength: ArrayLike, 

190 CO2_concentration: ArrayLike = CONSTANT_STANDARD_CO2_CONCENTRATION, 

191) -> NDArrayFloat: 

192 """ 

193 Compute the air refraction index :math:`n_s` from the specified wavelength 

194 :math:`\\lambda` in micrometers (:math:`\\mu m`) using the 

195 *Bodhaine, Wood, Dutton and Slusser (1999)* method. 

196 

197 Parameters 

198 ---------- 

199 wavelength 

200 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

201 CO2_concentration 

202 :math:`CO_2` concentration in parts per million (ppm). 

203 

204 Returns 

205 ------- 

206 :class:`numpy.ndarray` 

207 Air refraction index :math:`n_s`. 

208 

209 Examples 

210 -------- 

211 >>> air_refraction_index_Bodhaine1999(0.555) # doctest: +ELLIPSIS 

212 1.0002777... 

213 """ 

214 

215 wl = as_float_array(wavelength) 

216 CO2_c = as_float_array(CO2_concentration) 

217 

218 # Converting from parts per million (ppm) to parts per volume (ppv). 

219 CO2_c = CO2_c * 1e-6 

220 

221 n = (1 + 0.54 * (CO2_c - 300e-6)) * (air_refraction_index_Peck1972(wl) - 1) + 1 

222 

223 return as_float(n) 

224 

225 

226def N2_depolarisation(wavelength: ArrayLike) -> NDArrayFloat: 

227 """ 

228 Compute the depolarisation of nitrogen :math:`N_2` as a function of 

229 wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

230 

231 Parameters 

232 ---------- 

233 wavelength 

234 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

235 

236 Returns 

237 ------- 

238 :class:`numpy.ndarray` 

239 Nitrogen :math:`N_2` depolarisation. 

240 

241 Examples 

242 -------- 

243 >>> N2_depolarisation(0.555) # doctest: +ELLIPSIS 

244 1.0350291... 

245 """ 

246 

247 wl = as_float_array(wavelength) 

248 

249 return 1.034 + 3.17 * 1.0e-4 * (1 / wl**2) 

250 

251 

252def O2_depolarisation(wavelength: ArrayLike) -> NDArrayFloat: 

253 """ 

254 Compute the depolarisation of oxygen :math:`O_2` as a function of 

255 wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

256 

257 Parameters 

258 ---------- 

259 wavelength 

260 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

261 

262 Returns 

263 ------- 

264 :class:`numpy.ndarray` 

265 Oxygen :math:`O_2` depolarisation. 

266 

267 Examples 

268 -------- 

269 >>> O2_depolarisation(0.555) # doctest: +ELLIPSIS 

270 1.1020225... 

271 """ 

272 

273 wl = as_float_array(wavelength) 

274 

275 return 1.096 + 1.385 * 1.0e-3 * (1 / wl**2) + 1.448 * 1.0e-4 * (1 / wl**4) 

276 

277 

278def F_air_Penndorf1957(wavelength: ArrayLike) -> NDArrayFloat: 

279 """ 

280 Compute the depolarisation term :math:`F(air)` or *King Factor* using 

281 the *Penndorf (1957)* method. 

282 

283 Parameters 

284 ---------- 

285 wavelength 

286 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

287 

288 Returns 

289 ------- 

290 :class:`numpy.ndarray` 

291 Air depolarisation term. 

292 

293 Notes 

294 ----- 

295 - The *wavelength* parameter is provided for consistency with other 

296 air depolarisation methods but is not used in this implementation, 

297 which returns a constant value. 

298 

299 Examples 

300 -------- 

301 >>> F_air_Penndorf1957(0.555) 

302 1.0608 

303 """ 

304 

305 wl = as_float_array(wavelength) 

306 

307 return as_float(np.resize(np.array([1.0608]), wl.shape)) 

308 

309 

310def F_air_Young1981(wavelength: ArrayLike) -> NDArrayFloat: 

311 """ 

312 Compute the depolarisation term :math:`F(air)` or *King Factor* using 

313 the *Young (1981)* method. 

314 

315 Parameters 

316 ---------- 

317 wavelength 

318 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

319 

320 Returns 

321 ------- 

322 :class:`numpy.ndarray` 

323 Air depolarisation term. 

324 

325 Notes 

326 ----- 

327 - The *wavelength* parameter is provided for consistency with other 

328 air depolarisation methods but is not used in this implementation, 

329 which returns a constant value. 

330 

331 Examples 

332 -------- 

333 >>> F_air_Young1981(0.555) 

334 1.048 

335 """ 

336 

337 wl = as_float_array(wavelength) 

338 

339 return as_float(np.resize(np.array([1.0480]), wl.shape)) 

340 

341 

342def F_air_Bates1984(wavelength: ArrayLike) -> NDArrayFloat: 

343 """ 

344 Compute the depolarisation term :math:`F(air)` or *King Factor* using 

345 the *Bates (1984)* method. 

346 (:math:`\\mu m`) using *Bates (1984)* method. 

347 

348 Parameters 

349 ---------- 

350 wavelength 

351 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

352 

353 Returns 

354 ------- 

355 :class:`numpy.ndarray` 

356 Air depolarisation term. 

357 

358 Examples 

359 -------- 

360 >>> F_air_Bates1984(0.555) # doctest: +ELLIPSIS 

361 1.0481535... 

362 """ 

363 

364 O2 = O2_depolarisation(wavelength) 

365 N2 = N2_depolarisation(wavelength) 

366 Ar = 1.00 

367 CO2 = 1.15 

368 

369 return (78.084 * N2 + 20.946 * O2 + CO2 + Ar) / (78.084 + 20.946 + Ar + CO2) 

370 

371 

372def F_air_Bodhaine1999( 

373 wavelength: ArrayLike, 

374 CO2_concentration: ArrayLike = CONSTANT_STANDARD_CO2_CONCENTRATION, 

375) -> NDArrayFloat: 

376 """ 

377 Compute the depolarisation term :math:`F(air)` or *King Factor* as a 

378 function of wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`) 

379 and :math:`CO_2` concentration in parts per million (ppm) using the 

380 *Bodhaine, Wood, Dutton and Slusser (1999)* method. 

381 

382 Parameters 

383 ---------- 

384 wavelength 

385 Wavelength :math:`\\lambda` in micrometers (:math:`\\mu m`). 

386 CO2_concentration 

387 :math:`CO_2` concentration in parts per million (ppm). 

388 

389 Returns 

390 ------- 

391 :class:`numpy.ndarray` 

392 Air depolarisation term. 

393 

394 Examples 

395 -------- 

396 >>> F_air_Bodhaine1999(0.555) # doctest: +ELLIPSIS 

397 1.0487697... 

398 """ 

399 

400 O2 = O2_depolarisation(wavelength) 

401 N2 = N2_depolarisation(wavelength) 

402 CO2_c = as_float_array(CO2_concentration) 

403 

404 # Converting from parts per million (ppm) to parts per volume per percent. 

405 CO2_c = CO2_c * 1e-4 

406 

407 return (78.084 * N2 + 20.946 * O2 + 0.934 * 1 + CO2_c * 1.15) / ( 

408 78.084 + 20.946 + 0.934 + CO2_c 

409 ) 

410 

411 

412def molecular_density( 

413 temperature: ArrayLike = CONSTANT_STANDARD_AIR_TEMPERATURE, 

414 avogadro_constant: ArrayLike = CONSTANT_AVOGADRO, 

415) -> NDArrayFloat: 

416 """ 

417 Compute the molecular density :math:`N_s` (molecules :math:`cm^{-3}`) 

418 as function of air temperature :math:`T[K]` in kelvin degrees. 

419 

420 Parameters 

421 ---------- 

422 temperature 

423 Air temperature :math:`T[K]` in kelvin degrees. 

424 avogadro_constant 

425 *Avogadro*'s number (molecules :math:`mol^{-1}`). 

426 

427 Returns 

428 ------- 

429 :class:`numpy.ndarray` 

430 Molecular density :math:`N_s` (molecules :math:`cm^{-3}`). 

431 

432 Notes 

433 ----- 

434 - The *Avogadro*'s number used in this implementation is the one 

435 specified by the Committee on Data for Science and Technology 

436 (CODATA): :math:`6.02214179 \\times 10^{23}`, which differs from 

437 the reference :cite:`Bodhaine1999a` value 

438 :math:`6.0221367 \\times 10^{23}`. 

439 

440 Examples 

441 -------- 

442 >>> molecular_density(288.15) # doctest: +ELLIPSIS 

443 2.5469021...e+19 

444 >>> molecular_density(288.15, 6.0221367e23) # doctest: +ELLIPSIS 

445 2.5468999...e+19 

446 """ 

447 

448 T = as_float_array(temperature) 

449 avogadro_constant = as_float_array(avogadro_constant) 

450 

451 with sdiv_mode(): 

452 return (avogadro_constant / 22.4141) * sdiv(273.15, T) * (1 / 1000) 

453 

454 

455def mean_molecular_weights( 

456 CO2_concentration: ArrayLike = CONSTANT_STANDARD_CO2_CONCENTRATION, 

457) -> NDArrayFloat: 

458 """ 

459 Compute the mean molecular weights :math:`m_a` for dry air as a function 

460 of :math:`CO_2` concentration in parts per million (ppm). 

461 

462 Parameters 

463 ---------- 

464 CO2_concentration 

465 :math:`CO_2` concentration in parts per million (ppm). 

466 

467 Returns 

468 ------- 

469 :class:`numpy.ndarray` 

470 Mean molecular weights :math:`m_a` for dry air. 

471 

472 Examples 

473 -------- 

474 >>> mean_molecular_weights() # doctest: +ELLIPSIS 

475 28.9640166... 

476 """ 

477 

478 CO2_concentration = as_float_array(CO2_concentration) 

479 

480 CO2_c = CO2_concentration * 1.0e-6 

481 

482 return 15.0556 * CO2_c + 28.9595 

483 

484 

485def gravity_List1968( 

486 latitude: ArrayLike = CONSTANT_DEFAULT_LATITUDE, 

487 altitude: ArrayLike = CONSTANT_DEFAULT_ALTITUDE, 

488) -> NDArrayFloat: 

489 """ 

490 Compute the gravity :math:`g` in :math:`cm/s^2` (gal) representative of 

491 the mass-weighted column of air molecules above the site at the specified 

492 latitude and altitude using the *List (1968)* method. 

493 

494 Parameters 

495 ---------- 

496 latitude 

497 Latitude of the site in degrees. 

498 altitude 

499 Altitude of the site in meters. 

500 

501 Returns 

502 ------- 

503 :class:`numpy.ndarray` 

504 Gravity :math:`g` in :math:`cm/s^2` (gal). 

505 

506 Examples 

507 -------- 

508 >>> gravity_List1968() # doctest: +ELLIPSIS 

509 978.0356070... 

510 >>> gravity_List1968(0.0, 1500.0) # doctest: +ELLIPSIS 

511 977.5726106... 

512 

513 Gravity :math:`g` for Paris: 

514 

515 >>> gravity_List1968(48.8567, 35.0) # doctest: +ELLIPSIS 

516 980.9524178... 

517 """ 

518 

519 latitude = as_float_array(latitude) 

520 altitude = as_float_array(altitude) 

521 

522 cos2phi = np.cos(2 * np.radians(latitude)) 

523 

524 # Sea level acceleration of gravity. 

525 g0 = 980.6160 * (1 - 0.0026373 * cos2phi + 0.0000059 * cos2phi**2) 

526 

527 return ( 

528 g0 

529 - (3.085462e-4 + 2.27e-7 * cos2phi) * altitude 

530 + (7.254e-11 + 1.0e-13 * cos2phi) * altitude**2 

531 - (1.517e-17 + 6e-20 * cos2phi) * altitude**3 

532 ) 

533 

534 

535def scattering_cross_section( 

536 wavelength: ArrayLike, 

537 CO2_concentration: ArrayLike = CONSTANT_STANDARD_CO2_CONCENTRATION, 

538 temperature: ArrayLike = CONSTANT_STANDARD_AIR_TEMPERATURE, 

539 avogadro_constant: ArrayLike = CONSTANT_AVOGADRO, 

540 n_s_function: Callable = air_refraction_index_Bodhaine1999, 

541 F_air_function: Callable = F_air_Bodhaine1999, 

542) -> NDArrayFloat: 

543 """ 

544 Compute the scattering cross-section per molecule :math:`\\sigma` of dry 

545 air as a function of wavelength :math:`\\lambda` in centimeters (cm) 

546 using the specified :math:`CO_2` concentration in parts per million 

547 (ppm) and temperature :math:`T[K]` in kelvin degrees following the 

548 *Van de Hulst (1957)* method. 

549 

550 Parameters 

551 ---------- 

552 wavelength 

553 Wavelength :math:`\\lambda` in centimeters (cm). 

554 CO2_concentration 

555 :math:`CO_2` concentration in parts per million (ppm). 

556 temperature 

557 Air temperature :math:`T[K]` in kelvin degrees. 

558 avogadro_constant 

559 *Avogadro*'s number (molecules :math:`mol^{-1}`). 

560 n_s_function 

561 Air refraction index :math:`n_s` computation method. 

562 F_air_function 

563 :math:`(6+3_p)/(6-7_p)`, the depolarisation term :math:`F(air)` or 

564 *King Factor* computation method. 

565 

566 Returns 

567 ------- 

568 :class:`numpy.ndarray` 

569 Scattering cross-section per molecule :math:`\\sigma` of dry air. 

570 

571 Warnings 

572 -------- 

573 Unlike most objects of :mod:`colour.phenomena.rayleigh` module, 

574 :func:`colour.scattering_cross_section` expects wavelength 

575 :math:`\\lambda` to be expressed in centimeters (cm). 

576 

577 References 

578 ---------- 

579 :cite:`Bodhaine1999a`, :cite:`Wikipedia2001c` 

580 

581 Examples 

582 -------- 

583 >>> scattering_cross_section(555 * 10e-8) # doctest: +ELLIPSIS 

584 4.3466692...e-27 

585 """ 

586 

587 wl = as_float_array(wavelength) 

588 CO2_c = as_float_array(CO2_concentration) 

589 temperature = as_float_array(temperature) 

590 

591 wl_micrometers = wl * 10e3 

592 

593 N_s = molecular_density(temperature, avogadro_constant) 

594 n_s = n_s_function(wl_micrometers) 

595 # n_s = n_s_function(**filter_kwargs( 

596 # n_s_function, wavelength=wl_micrometers, CO2_concentration=CO2_c)) 

597 F_air = F_air_function( 

598 **filter_kwargs( 

599 F_air_function, wavelength=wl_micrometers, CO2_concentration=CO2_c 

600 ) 

601 ) 

602 

603 sigma = 24 * np.pi**3 * (n_s**2 - 1) ** 2 / (wl**4 * N_s**2 * (n_s**2 + 2) ** 2) 

604 sigma *= F_air 

605 

606 return sigma 

607 

608 

609def rayleigh_optical_depth( 

610 wavelength: ArrayLike, 

611 CO2_concentration: ArrayLike = CONSTANT_STANDARD_CO2_CONCENTRATION, 

612 temperature: ArrayLike = CONSTANT_STANDARD_AIR_TEMPERATURE, 

613 pressure: ArrayLike = CONSTANT_AVERAGE_PRESSURE_MEAN_SEA_LEVEL, 

614 latitude: ArrayLike = CONSTANT_DEFAULT_LATITUDE, 

615 altitude: ArrayLike = CONSTANT_DEFAULT_ALTITUDE, 

616 avogadro_constant: ArrayLike = CONSTANT_AVOGADRO, 

617 n_s_function: Callable = air_refraction_index_Bodhaine1999, 

618 F_air_function: Callable = F_air_Bodhaine1999, 

619) -> NDArrayFloat: 

620 """ 

621 Compute the *Rayleigh* optical depth :math:`T_r(\\lambda)` as a function 

622 of wavelength :math:`\\lambda` in centimeters (cm). 

623 

624 Parameters 

625 ---------- 

626 wavelength 

627 Wavelength :math:`\\lambda` in centimeters (cm). 

628 CO2_concentration 

629 :math:`CO_2` concentration in parts per million (ppm). 

630 temperature 

631 Air temperature :math:`T[K]` in kelvin degrees. 

632 pressure 

633 Surface pressure :math:`P` of the measurement site. 

634 latitude 

635 Latitude of the site in degrees. 

636 altitude 

637 Altitude of the site in meters. 

638 avogadro_constant 

639 *Avogadro*'s number (molecules :math:`mol^{-1}`). 

640 n_s_function 

641 Air refraction index :math:`n_s` computation method. 

642 F_air_function 

643 :math:`(6+3_p)/(6-7_p)`, the depolarisation term :math:`F(air)` 

644 or *King Factor* computation method. 

645 

646 Returns 

647 ------- 

648 :class:`numpy.ndarray` 

649 *Rayleigh* optical depth :math:`T_r(\\lambda)`. 

650 

651 Warnings 

652 -------- 

653 Unlike most objects of :mod:`colour.phenomena.rayleigh` module, 

654 :func:`colour.phenomena.rayleigh_optical_depth` expects wavelength 

655 :math:`\\lambda` to be expressed in centimeters (cm). 

656 

657 References 

658 ---------- 

659 :cite:`Bodhaine1999a`, :cite:`Wikipedia2001c` 

660 

661 Examples 

662 -------- 

663 >>> rayleigh_optical_depth(555 * 10e-8) # doctest: +ELLIPSIS 

664 0.0936290... 

665 """ 

666 

667 wavelength = as_float_array(wavelength) 

668 CO2_c = as_float_array(CO2_concentration) 

669 pressure = as_float_array(pressure) 

670 latitude = as_float_array(latitude) 

671 altitude = as_float_array(altitude) 

672 avogadro_constant = as_float_array(avogadro_constant) 

673 # Conversion from pascal to dyne/cm2. 

674 P = as_float_array(pressure * 10) 

675 

676 sigma = scattering_cross_section( 

677 wavelength, 

678 CO2_c, 

679 temperature, 

680 avogadro_constant, 

681 n_s_function, 

682 F_air_function, 

683 ) 

684 

685 m_a = mean_molecular_weights(CO2_c) 

686 g = gravity_List1968(latitude, altitude) 

687 

688 T_R = sigma * (P * avogadro_constant) / (m_a * g) 

689 

690 return as_float(T_R) 

691 

692 

693rayleigh_scattering = rayleigh_optical_depth 

694 

695 

696def sd_rayleigh_scattering( 

697 shape: SpectralShape = SPECTRAL_SHAPE_DEFAULT, 

698 CO2_concentration: ArrayLike = CONSTANT_STANDARD_CO2_CONCENTRATION, 

699 temperature: ArrayLike = CONSTANT_STANDARD_AIR_TEMPERATURE, 

700 pressure: ArrayLike = CONSTANT_AVERAGE_PRESSURE_MEAN_SEA_LEVEL, 

701 latitude: ArrayLike = CONSTANT_DEFAULT_LATITUDE, 

702 altitude: ArrayLike = CONSTANT_DEFAULT_ALTITUDE, 

703 avogadro_constant: ArrayLike = CONSTANT_AVOGADRO, 

704 n_s_function: Callable = air_refraction_index_Bodhaine1999, 

705 F_air_function: Callable = F_air_Bodhaine1999, 

706) -> SpectralDistribution: 

707 """ 

708 Generate *Rayleigh* scattering spectral distribution for the specified 

709 spectral shape. 

710 

711 Parameters 

712 ---------- 

713 shape 

714 Spectral shape used to create the *Rayleigh* scattering spectral 

715 distribution. 

716 CO2_concentration 

717 :math:`CO_2` concentration in parts per million (ppm). 

718 temperature 

719 Air temperature :math:`T[K]` in kelvin degrees. 

720 pressure 

721 Surface pressure :math:`P` of the measurement site. 

722 latitude 

723 Latitude of the site in degrees. 

724 altitude 

725 Altitude of the site in meters. 

726 avogadro_constant 

727 *Avogadro*'s number (molecules :math:`mol^{-1}`). 

728 n_s_function 

729 Air refraction index :math:`n_s` computation method. 

730 F_air_function 

731 :math:`(6+3_p)/(6-7_p)`, the depolarisation term :math:`F(air)` or 

732 *King Factor* computation method. 

733 

734 Returns 

735 ------- 

736 :class:`colour.SpectralDistribution` 

737 *Rayleigh* optical depth spectral distribution. 

738 

739 References 

740 ---------- 

741 :cite:`Bodhaine1999a`, :cite:`Wikipedia2001c` 

742 

743 Examples 

744 -------- 

745 >>> from colour.utilities import numpy_print_options 

746 >>> with numpy_print_options(suppress=True): 

747 ... sd_rayleigh_scattering() # doctest: +ELLIPSIS 

748 SpectralDistribution([[ 360. , 0.5602465...], 

749 [ 361. , 0.5537481...], 

750 [ 362. , 0.5473446...], 

751 [ 363. , 0.5410345...], 

752 [ 364. , 0.5348161...], 

753 [ 365. , 0.5286877...], 

754 [ 366. , 0.5226477...], 

755 [ 367. , 0.5166948...], 

756 [ 368. , 0.5108272...], 

757 [ 369. , 0.5050436...], 

758 [ 370. , 0.4993425...], 

759 [ 371. , 0.4937224...], 

760 [ 372. , 0.4881820...], 

761 [ 373. , 0.4827199...], 

762 [ 374. , 0.4773348...], 

763 [ 375. , 0.4720253...], 

764 [ 376. , 0.4667902...], 

765 [ 377. , 0.4616282...], 

766 [ 378. , 0.4565380...], 

767 [ 379. , 0.4515186...], 

768 [ 380. , 0.4465686...], 

769 [ 381. , 0.4416869...], 

770 [ 382. , 0.4368724...], 

771 [ 383. , 0.4321240...], 

772 [ 384. , 0.4274405...], 

773 [ 385. , 0.4228209...], 

774 [ 386. , 0.4182641...], 

775 [ 387. , 0.4137692...], 

776 [ 388. , 0.4093350...], 

777 [ 389. , 0.4049607...], 

778 [ 390. , 0.4006451...], 

779 [ 391. , 0.3963874...], 

780 [ 392. , 0.3921867...], 

781 [ 393. , 0.3880419...], 

782 [ 394. , 0.3839523...], 

783 [ 395. , 0.3799169...], 

784 [ 396. , 0.3759348...], 

785 [ 397. , 0.3720053...], 

786 [ 398. , 0.3681274...], 

787 [ 399. , 0.3643003...], 

788 [ 400. , 0.3605233...], 

789 [ 401. , 0.3567956...], 

790 [ 402. , 0.3531163...], 

791 [ 403. , 0.3494847...], 

792 [ 404. , 0.3459001...], 

793 [ 405. , 0.3423617...], 

794 [ 406. , 0.3388689...], 

795 [ 407. , 0.3354208...], 

796 [ 408. , 0.3320169...], 

797 [ 409. , 0.3286563...], 

798 [ 410. , 0.3253386...], 

799 [ 411. , 0.3220629...], 

800 [ 412. , 0.3188287...], 

801 [ 413. , 0.3156354...], 

802 [ 414. , 0.3124822...], 

803 [ 415. , 0.3093687...], 

804 [ 416. , 0.3062941...], 

805 [ 417. , 0.3032579...], 

806 [ 418. , 0.3002596...], 

807 [ 419. , 0.2972985...], 

808 [ 420. , 0.2943741...], 

809 [ 421. , 0.2914858...], 

810 [ 422. , 0.2886332...], 

811 [ 423. , 0.2858157...], 

812 [ 424. , 0.2830327...], 

813 [ 425. , 0.2802837...], 

814 [ 426. , 0.2775683...], 

815 [ 427. , 0.2748860...], 

816 [ 428. , 0.2722362...], 

817 [ 429. , 0.2696185...], 

818 [ 430. , 0.2670324...], 

819 [ 431. , 0.2644775...], 

820 [ 432. , 0.2619533...], 

821 [ 433. , 0.2594594...], 

822 [ 434. , 0.2569952...], 

823 [ 435. , 0.2545605...], 

824 [ 436. , 0.2521548...], 

825 [ 437. , 0.2497776...], 

826 [ 438. , 0.2474285...], 

827 [ 439. , 0.2451072...], 

828 [ 440. , 0.2428133...], 

829 [ 441. , 0.2405463...], 

830 [ 442. , 0.2383059...], 

831 [ 443. , 0.2360916...], 

832 [ 444. , 0.2339033...], 

833 [ 445. , 0.2317404...], 

834 [ 446. , 0.2296026...], 

835 [ 447. , 0.2274895...], 

836 [ 448. , 0.2254009...], 

837 [ 449. , 0.2233364...], 

838 [ 450. , 0.2212956...], 

839 [ 451. , 0.2192782...], 

840 [ 452. , 0.2172839...], 

841 [ 453. , 0.2153124...], 

842 [ 454. , 0.2133633...], 

843 [ 455. , 0.2114364...], 

844 [ 456. , 0.2095313...], 

845 [ 457. , 0.2076478...], 

846 [ 458. , 0.2057855...], 

847 [ 459. , 0.2039442...], 

848 [ 460. , 0.2021235...], 

849 [ 461. , 0.2003233...], 

850 [ 462. , 0.1985432...], 

851 [ 463. , 0.1967829...], 

852 [ 464. , 0.1950423...], 

853 [ 465. , 0.1933209...], 

854 [ 466. , 0.1916186...], 

855 [ 467. , 0.1899351...], 

856 [ 468. , 0.1882702...], 

857 [ 469. , 0.1866236...], 

858 [ 470. , 0.1849951...], 

859 [ 471. , 0.1833844...], 

860 [ 472. , 0.1817913...], 

861 [ 473. , 0.1802156...], 

862 [ 474. , 0.1786570...], 

863 [ 475. , 0.1771153...], 

864 [ 476. , 0.1755903...], 

865 [ 477. , 0.1740818...], 

866 [ 478. , 0.1725895...], 

867 [ 479. , 0.1711133...], 

868 [ 480. , 0.1696529...], 

869 [ 481. , 0.1682082...], 

870 [ 482. , 0.1667789...], 

871 [ 483. , 0.1653648...], 

872 [ 484. , 0.1639658...], 

873 [ 485. , 0.1625816...], 

874 [ 486. , 0.1612121...], 

875 [ 487. , 0.1598570...], 

876 [ 488. , 0.1585163...], 

877 [ 489. , 0.1571896...], 

878 [ 490. , 0.1558769...], 

879 [ 491. , 0.1545779...], 

880 [ 492. , 0.1532925...], 

881 [ 493. , 0.1520205...], 

882 [ 494. , 0.1507617...], 

883 [ 495. , 0.1495160...], 

884 [ 496. , 0.1482832...], 

885 [ 497. , 0.1470632...], 

886 [ 498. , 0.1458558...], 

887 [ 499. , 0.1446607...], 

888 [ 500. , 0.1434780...], 

889 [ 501. , 0.1423074...], 

890 [ 502. , 0.1411488...], 

891 [ 503. , 0.140002 ...], 

892 [ 504. , 0.1388668...], 

893 [ 505. , 0.1377433...], 

894 [ 506. , 0.1366311...], 

895 [ 507. , 0.1355301...], 

896 [ 508. , 0.1344403...], 

897 [ 509. , 0.1333615...], 

898 [ 510. , 0.1322936...], 

899 [ 511. , 0.1312363...], 

900 [ 512. , 0.1301897...], 

901 [ 513. , 0.1291535...], 

902 [ 514. , 0.1281277...], 

903 [ 515. , 0.1271121...], 

904 [ 516. , 0.1261065...], 

905 [ 517. , 0.1251110...], 

906 [ 518. , 0.1241253...], 

907 [ 519. , 0.1231493...], 

908 [ 520. , 0.1221829...], 

909 [ 521. , 0.1212261...], 

910 [ 522. , 0.1202786...], 

911 [ 523. , 0.1193405...], 

912 [ 524. , 0.1184115...], 

913 [ 525. , 0.1174915...], 

914 [ 526. , 0.1165806...], 

915 [ 527. , 0.1156784...], 

916 [ 528. , 0.1147851...], 

917 [ 529. , 0.1139004...], 

918 [ 530. , 0.1130242...], 

919 [ 531. , 0.1121564...], 

920 [ 532. , 0.1112971...], 

921 [ 533. , 0.1104459...], 

922 [ 534. , 0.1096030...], 

923 [ 535. , 0.1087681...], 

924 [ 536. , 0.1079411...], 

925 [ 537. , 0.1071221...], 

926 [ 538. , 0.1063108...], 

927 [ 539. , 0.1055072...], 

928 [ 540. , 0.1047113...], 

929 [ 541. , 0.1039229...], 

930 [ 542. , 0.1031419...], 

931 [ 543. , 0.1023682...], 

932 [ 544. , 0.1016019...], 

933 [ 545. , 0.1008427...], 

934 [ 546. , 0.1000906...], 

935 [ 547. , 0.0993456...], 

936 [ 548. , 0.0986075...], 

937 [ 549. , 0.0978763...], 

938 [ 550. , 0.0971519...], 

939 [ 551. , 0.0964342...], 

940 [ 552. , 0.0957231...], 

941 [ 553. , 0.0950186...], 

942 [ 554. , 0.0943206...], 

943 [ 555. , 0.0936290...], 

944 [ 556. , 0.0929438...], 

945 [ 557. , 0.0922649...], 

946 [ 558. , 0.0915922...], 

947 [ 559. , 0.0909256...], 

948 [ 560. , 0.0902651...], 

949 [ 561. , 0.0896106...], 

950 [ 562. , 0.0889620...], 

951 [ 563. , 0.0883194...], 

952 [ 564. , 0.0876825...], 

953 [ 565. , 0.0870514...], 

954 [ 566. , 0.0864260...], 

955 [ 567. , 0.0858063...], 

956 [ 568. , 0.0851921...], 

957 [ 569. , 0.0845834...], 

958 [ 570. , 0.0839801...], 

959 [ 571. , 0.0833822...], 

960 [ 572. , 0.0827897...], 

961 [ 573. , 0.0822025...], 

962 [ 574. , 0.0816204...], 

963 [ 575. , 0.0810436...], 

964 [ 576. , 0.0804718...], 

965 [ 577. , 0.0799051...], 

966 [ 578. , 0.0793434...], 

967 [ 579. , 0.0787866...], 

968 [ 580. , 0.0782347...], 

969 [ 581. , 0.0776877...], 

970 [ 582. , 0.0771454...], 

971 [ 583. , 0.0766079...], 

972 [ 584. , 0.0760751...], 

973 [ 585. , 0.0755469...], 

974 [ 586. , 0.0750234...], 

975 [ 587. , 0.0745043...], 

976 [ 588. , 0.0739898...], 

977 [ 589. , 0.0734797...], 

978 [ 590. , 0.0729740...], 

979 [ 591. , 0.0724727...], 

980 [ 592. , 0.0719757...], 

981 [ 593. , 0.0714830...], 

982 [ 594. , 0.0709944...], 

983 [ 595. , 0.0705101...], 

984 [ 596. , 0.0700299...], 

985 [ 597. , 0.0695538...], 

986 [ 598. , 0.0690818...], 

987 [ 599. , 0.0686137...], 

988 [ 600. , 0.0681497...], 

989 [ 601. , 0.0676895...], 

990 [ 602. , 0.0672333...], 

991 [ 603. , 0.0667809...], 

992 [ 604. , 0.0663323...], 

993 [ 605. , 0.0658875...], 

994 [ 606. , 0.0654464...], 

995 [ 607. , 0.0650091...], 

996 [ 608. , 0.0645753...], 

997 [ 609. , 0.0641453...], 

998 [ 610. , 0.0637187...], 

999 [ 611. , 0.0632958...], 

1000 [ 612. , 0.0628764...], 

1001 [ 613. , 0.0624604...], 

1002 [ 614. , 0.0620479...], 

1003 [ 615. , 0.0616388...], 

1004 [ 616. , 0.0612331...], 

1005 [ 617. , 0.0608307...], 

1006 [ 618. , 0.0604316...], 

1007 [ 619. , 0.0600358...], 

1008 [ 620. , 0.0596433...], 

1009 [ 621. , 0.0592539...], 

1010 [ 622. , 0.0588678...], 

1011 [ 623. , 0.0584848...], 

1012 [ 624. , 0.0581049...], 

1013 [ 625. , 0.0577281...], 

1014 [ 626. , 0.0573544...], 

1015 [ 627. , 0.0569837...], 

1016 [ 628. , 0.0566160...], 

1017 [ 629. , 0.0562513...], 

1018 [ 630. , 0.0558895...], 

1019 [ 631. , 0.0555306...], 

1020 [ 632. , 0.0551746...], 

1021 [ 633. , 0.0548215...], 

1022 [ 634. , 0.0544712...], 

1023 [ 635. , 0.0541237...], 

1024 [ 636. , 0.0537789...], 

1025 [ 637. , 0.0534369...], 

1026 [ 638. , 0.0530977...], 

1027 [ 639. , 0.0527611...], 

1028 [ 640. , 0.0524272...], 

1029 [ 641. , 0.0520960...], 

1030 [ 642. , 0.0517674...], 

1031 [ 643. , 0.0514413...], 

1032 [ 644. , 0.0511179...], 

1033 [ 645. , 0.0507970...], 

1034 [ 646. , 0.0504786...], 

1035 [ 647. , 0.0501627...], 

1036 [ 648. , 0.0498493...], 

1037 [ 649. , 0.0495383...], 

1038 [ 650. , 0.0492298...], 

1039 [ 651. , 0.0489236...], 

1040 [ 652. , 0.0486199...], 

1041 [ 653. , 0.0483185...], 

1042 [ 654. , 0.0480194...], 

1043 [ 655. , 0.0477227...], 

1044 [ 656. , 0.0474283...], 

1045 [ 657. , 0.0471361...], 

1046 [ 658. , 0.0468462...], 

1047 [ 659. , 0.0465585...], 

1048 [ 660. , 0.0462730...], 

1049 [ 661. , 0.0459898...], 

1050 [ 662. , 0.0457087...], 

1051 [ 663. , 0.0454297...], 

1052 [ 664. , 0.0451529...], 

1053 [ 665. , 0.0448782...], 

1054 [ 666. , 0.0446055...], 

1055 [ 667. , 0.0443350...], 

1056 [ 668. , 0.0440665...], 

1057 [ 669. , 0.0438000...], 

1058 [ 670. , 0.0435356...], 

1059 [ 671. , 0.0432731...], 

1060 [ 672. , 0.0430127...], 

1061 [ 673. , 0.0427542...], 

1062 [ 674. , 0.0424976...], 

1063 [ 675. , 0.0422430...], 

1064 [ 676. , 0.0419902...], 

1065 [ 677. , 0.0417394...], 

1066 [ 678. , 0.0414905...], 

1067 [ 679. , 0.0412434...], 

1068 [ 680. , 0.0409981...], 

1069 [ 681. , 0.0407547...], 

1070 [ 682. , 0.0405131...], 

1071 [ 683. , 0.0402732...], 

1072 [ 684. , 0.0400352...], 

1073 [ 685. , 0.0397989...], 

1074 [ 686. , 0.0395643...], 

1075 [ 687. , 0.0393315...], 

1076 [ 688. , 0.0391004...], 

1077 [ 689. , 0.0388710...], 

1078 [ 690. , 0.0386433...], 

1079 [ 691. , 0.0384173...], 

1080 [ 692. , 0.0381929...], 

1081 [ 693. , 0.0379701...], 

1082 [ 694. , 0.0377490...], 

1083 [ 695. , 0.0375295...], 

1084 [ 696. , 0.0373115...], 

1085 [ 697. , 0.0370952...], 

1086 [ 698. , 0.0368804...], 

1087 [ 699. , 0.0366672...], 

1088 [ 700. , 0.0364556...], 

1089 [ 701. , 0.0362454...], 

1090 [ 702. , 0.0360368...], 

1091 [ 703. , 0.0358297...], 

1092 [ 704. , 0.0356241...], 

1093 [ 705. , 0.0354199...], 

1094 [ 706. , 0.0352172...], 

1095 [ 707. , 0.0350160...], 

1096 [ 708. , 0.0348162...], 

1097 [ 709. , 0.0346178...], 

1098 [ 710. , 0.0344208...], 

1099 [ 711. , 0.0342253...], 

1100 [ 712. , 0.0340311...], 

1101 [ 713. , 0.0338383...], 

1102 [ 714. , 0.0336469...], 

1103 [ 715. , 0.0334569...], 

1104 [ 716. , 0.0332681...], 

1105 [ 717. , 0.0330807...], 

1106 [ 718. , 0.0328947...], 

1107 [ 719. , 0.0327099...], 

1108 [ 720. , 0.0325264...], 

1109 [ 721. , 0.0323443...], 

1110 [ 722. , 0.0321634...], 

1111 [ 723. , 0.0319837...], 

1112 [ 724. , 0.0318054...], 

1113 [ 725. , 0.0316282...], 

1114 [ 726. , 0.0314523...], 

1115 [ 727. , 0.0312777...], 

1116 [ 728. , 0.0311042...], 

1117 [ 729. , 0.0309319...], 

1118 [ 730. , 0.0307609...], 

1119 [ 731. , 0.0305910...], 

1120 [ 732. , 0.0304223...], 

1121 [ 733. , 0.0302548...], 

1122 [ 734. , 0.0300884...], 

1123 [ 735. , 0.0299231...], 

1124 [ 736. , 0.0297590...], 

1125 [ 737. , 0.0295960...], 

1126 [ 738. , 0.0294342...], 

1127 [ 739. , 0.0292734...], 

1128 [ 740. , 0.0291138...], 

1129 [ 741. , 0.0289552...], 

1130 [ 742. , 0.0287977...], 

1131 [ 743. , 0.0286413...], 

1132 [ 744. , 0.0284859...], 

1133 [ 745. , 0.0283316...], 

1134 [ 746. , 0.0281784...], 

1135 [ 747. , 0.0280262...], 

1136 [ 748. , 0.0278750...], 

1137 [ 749. , 0.0277248...], 

1138 [ 750. , 0.0275757...], 

1139 [ 751. , 0.0274275...], 

1140 [ 752. , 0.0272804...], 

1141 [ 753. , 0.0271342...], 

1142 [ 754. , 0.0269890...], 

1143 [ 755. , 0.0268448...], 

1144 [ 756. , 0.0267015...], 

1145 [ 757. , 0.0265592...], 

1146 [ 758. , 0.0264179...], 

1147 [ 759. , 0.0262775...], 

1148 [ 760. , 0.0261380...], 

1149 [ 761. , 0.0259995...], 

1150 [ 762. , 0.0258618...], 

1151 [ 763. , 0.0257251...], 

1152 [ 764. , 0.0255893...], 

1153 [ 765. , 0.0254544...], 

1154 [ 766. , 0.0253204...], 

1155 [ 767. , 0.0251872...], 

1156 [ 768. , 0.0250550...], 

1157 [ 769. , 0.0249236...], 

1158 [ 770. , 0.0247930...], 

1159 [ 771. , 0.0246633...], 

1160 [ 772. , 0.0245345...], 

1161 [ 773. , 0.0244065...], 

1162 [ 774. , 0.0242794...], 

1163 [ 775. , 0.0241530...], 

1164 [ 776. , 0.0240275...], 

1165 [ 777. , 0.0239029...], 

1166 [ 778. , 0.0237790...], 

1167 [ 779. , 0.0236559...], 

1168 [ 780. , 0.0235336...]], 

1169 SpragueInterpolator, 

1170 {}, 

1171 Extrapolator, 

1172 {'method': 'Constant', 'left': None, 'right': None}) 

1173 """ 

1174 

1175 return SpectralDistribution( 

1176 rayleigh_optical_depth( 

1177 shape.wavelengths * 10e-8, 

1178 CO2_concentration, 

1179 temperature, 

1180 pressure, 

1181 latitude, 

1182 altitude, 

1183 avogadro_constant, 

1184 n_s_function, 

1185 F_air_function, 

1186 ), 

1187 shape.wavelengths, 

1188 name=( 

1189 "Rayleigh Scattering - " 

1190 f"{CO2_concentration!r} ppm, " 

1191 f"{temperature!r} K, " 

1192 f"{pressure!r} Pa, " 

1193 f"{latitude!r} Degrees, " 

1194 f"{altitude!r} m" 

1195 ), 

1196 )