Coverage for colour/io/uprtek_sekonic.py: 100%

78 statements  

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

1""" 

2UPRTek and Sekonic Spectral Data 

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

4 

5Define input and output objects for parsing and handling *UPRTek* and 

6*Sekonic* spectral measurement data stored in *Pseudo-XLS* and *CSV* file 

7formats. 

8 

9- :class:`colour.SpectralDistribution_UPRTek` 

10- :class:`colour.SpectralDistribution_Sekonic` 

11""" 

12 

13from __future__ import annotations 

14 

15import csv 

16import json 

17import os 

18import re 

19import typing 

20from collections import defaultdict 

21 

22if typing.TYPE_CHECKING: 

23 from colour.hints import Any, PathLike 

24 

25from colour.hints import cast 

26from colour.io import SpectralDistribution_IESTM2714 

27from colour.utilities import as_float_array, as_float_scalar 

28 

29__author__ = "Colour Developers" 

30__copyright__ = "Copyright 2013 Colour Developers" 

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

32__maintainer__ = "Colour Developers" 

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

34__status__ = "Production" 

35 

36__all__ = [ 

37 "SpectralDistribution_UPRTek", 

38 "SpectralDistribution_Sekonic", 

39] 

40 

41 

42class SpectralDistribution_UPRTek(SpectralDistribution_IESTM2714): 

43 """ 

44 Implement support to read and write *IES TM-27-14* spectral data XML 

45 files from *UPRTek* *Pseudo-XLS* files. 

46 

47 This class extends :class:`SpectralDistribution_IESTM2714` to handle 

48 the specific *Pseudo-XLS* format used by *UPRTek* spectral measurement 

49 devices. The implementation parses metadata embedded in the file and 

50 converts it to the standard *IES TM-27-14* XML format. 

51 

52 Parameters 

53 ---------- 

54 path 

55 Absolute or relative path to the *UPRTek* *Pseudo-XLS* file. 

56 

57 Attributes 

58 ---------- 

59 - :attr:`~colour.SpectralDistribution_UPRTek.metadata` 

60 

61 Methods 

62 ------- 

63 - :meth:`~colour.SpectralDistribution_UPRTek.__init__` 

64 - :meth:`~colour.SpectralDistribution_UPRTek.__str__` 

65 - :meth:`~colour.SpectralDistribution_UPRTek.read` 

66 

67 Examples 

68 -------- 

69 >>> from os.path import dirname, join 

70 >>> from colour import SpectralShape 

71 >>> directory = join(dirname(__file__), "tests", "resources") 

72 >>> sd = SpectralDistribution_UPRTek( 

73 ... join(directory, "ESPD2021_0104_231446.xls") 

74 ... ) 

75 >>> print(sd.align(SpectralShape(380, 780, 10))) 

76 ... # doctest: +ELLIPSIS 

77 UPRTek 

78 ====== 

79 <BLANKLINE> 

80 Path : ... 

81 Spectral Quantity : irradiance 

82 Reflection Geometry : None 

83 Transmission Geometry : None 

84 Bandwidth (FWHM) : None 

85 Bandwidth Corrected : None 

86 <BLANKLINE> 

87 Header 

88 ------ 

89 <BLANKLINE> 

90 Manufacturer : UPRTek 

91 Catalog Number : None 

92 Description : None 

93 Document Creator : None 

94 Unique Identifier : None 

95 Measurement Equipment : CV600 

96 Laboratory : None 

97 Report Number : None 

98 Report Date : 2021/01/04_23:14:46 

99 Document Creation Date : None 

100 Comments : {...} 

101 <BLANKLINE> 

102 Spectral Data 

103 ------------- 

104 <BLANKLINE> 

105 [[ 3.80000000e+02 3.02670000e-02] 

106 [ 3.90000000e+02 3.52230000e-02] 

107 [ 4.00000000e+02 1.93250000e-02] 

108 [ 4.10000000e+02 2.94260000e-02] 

109 [ 4.20000000e+02 8.76780000e-02] 

110 [ 4.30000000e+02 6.32578000e-01] 

111 [ 4.40000000e+02 3.62565900e+00] 

112 [ 4.50000000e+02 1.42069180e+01] 

113 [ 4.60000000e+02 1.70112970e+01] 

114 [ 4.70000000e+02 1.19673130e+01] 

115 [ 4.80000000e+02 8.42736200e+00] 

116 [ 4.90000000e+02 7.97729800e+00] 

117 [ 5.00000000e+02 8.71903600e+00] 

118 [ 5.10000000e+02 9.55321500e+00] 

119 [ 5.20000000e+02 9.90610500e+00] 

120 [ 5.30000000e+02 9.91394400e+00] 

121 [ 5.40000000e+02 9.74738000e+00] 

122 [ 5.50000000e+02 9.53404900e+00] 

123 [ 5.60000000e+02 9.27392200e+00] 

124 [ 5.70000000e+02 9.02323400e+00] 

125 [ 5.80000000e+02 8.91788800e+00] 

126 [ 5.90000000e+02 9.11454600e+00] 

127 [ 6.00000000e+02 9.55787100e+00] 

128 [ 6.10000000e+02 1.00600760e+01] 

129 [ 6.20000000e+02 1.04846200e+01] 

130 [ 6.30000000e+02 1.05679540e+01] 

131 [ 6.40000000e+02 1.04359870e+01] 

132 [ 6.50000000e+02 9.82122300e+00] 

133 [ 6.60000000e+02 8.77578300e+00] 

134 [ 6.70000000e+02 7.56471800e+00] 

135 [ 6.80000000e+02 6.29808600e+00] 

136 [ 6.90000000e+02 5.15623400e+00] 

137 [ 7.00000000e+02 4.05390600e+00] 

138 [ 7.10000000e+02 3.06638600e+00] 

139 [ 7.20000000e+02 2.19250000e+00] 

140 [ 7.30000000e+02 1.53922800e+00] 

141 [ 7.40000000e+02 1.14938200e+00] 

142 [ 7.50000000e+02 9.05095000e-01] 

143 [ 7.60000000e+02 6.90947000e-01] 

144 [ 7.70000000e+02 5.08426000e-01] 

145 [ 7.80000000e+02 4.11766000e-01]] 

146 

147 >>> sd.header.comments 

148 '{"Model Name": "CV600", "Serial Number": "19J00789", \ 

149"Time": "2021/01/04_23:14:46", "Memo": [], "LUX": 695.154907, \ 

150"fc": 64.605476, "CCT": 5198.0, "Duv": -0.00062, "I-Time": 12000.0, \ 

151"X": 682.470886, "Y": 695.154907, "Z": 631.635071, "x": 0.339663, \ 

152"y": 0.345975, "u\\'": 0.209915, "v\\'": 0.481087, "LambdaP": 456.0, \ 

153"LambdaPValue": 18.404581, "CRI": 92.956993, "R1": 91.651062, \ 

154"R2": 93.014732, "R3": 97.032013, "R4": 93.513229, "R5": 92.48259, \ 

155"R6": 91.48687, "R7": 93.016129, "R8": 91.459312, "R9": 77.613075, \ 

156"R10": 86.981613, "R11": 94.841324, "R12": 74.139542, "R13": 91.073837, \ 

157"R14": 97.064323, "R15": 88.615669, "TLCI": 97.495056, "TLMF-A": 1.270032, \ 

158"SSI-A": 44.881924, "Rf": 87.234917, "Rg": 98.510712, "IRR": 2.607891}' 

159 >>> sd.metadata.keys() 

160 dict_keys(['Model Name', 'Serial Number', 'Time', 'Memo', 'LUX', 'fc', \ 

161'CCT', 'Duv', 'I-Time', 'X', 'Y', 'Z', 'x', 'y', "u'", "v'", 'LambdaP', \ 

162'LambdaPValue', 'CRI', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8', 'R9', \ 

163'R10', 'R11', 'R12', 'R13', 'R14', 'R15', 'TLCI', 'TLMF-A', 'SSI-A', 'Rf', \ 

164'Rg', 'IRR']) 

165 >>> sd.write(join(directory, "ESPD2021_0104_231446.spdx")) 

166 ... # doctest: +SKIP 

167 """ 

168 

169 _DELIMITER: str = "\t" 

170 _SPECTRAL_SECTION: str = "380" 

171 _SPECTRAL_DATA_PATTERN: str = "(\\d{3})nm" 

172 

173 def __init__(self, path: str | PathLike, **kwargs: Any) -> None: 

174 self._metadata: dict = {} 

175 

176 super().__init__(path, **kwargs) 

177 

178 @property 

179 def metadata(self) -> dict: 

180 """ 

181 Getter for the dataset metadata. 

182 

183 Returns 

184 ------- 

185 :class:`dict` 

186 Dataset metadata containing information about the data source, 

187 structure, and properties. 

188 """ 

189 

190 return self._metadata 

191 

192 def __str__(self) -> str: 

193 """ 

194 Return a formatted string representation of the *UPRTek* spectral 

195 distribution. 

196 

197 Returns 

198 ------- 

199 :class:`str` 

200 Formatted string representation. 

201 

202 Examples 

203 -------- 

204 >>> from os.path import dirname, join 

205 >>> from colour import SpectralShape 

206 >>> directory = join(dirname(__file__), "tests", "resources") 

207 >>> sd = SpectralDistribution_UPRTek( 

208 ... join(directory, "ESPD2021_0104_231446.xls") 

209 ... ) 

210 >>> print(sd.read().align(SpectralShape(380, 780, 10))) 

211 ... # doctest: +ELLIPSIS 

212 UPRTek 

213 ====== 

214 <BLANKLINE> 

215 Path : ... 

216 Spectral Quantity : irradiance 

217 Reflection Geometry : None 

218 Transmission Geometry : None 

219 Bandwidth (FWHM) : None 

220 Bandwidth Corrected : None 

221 <BLANKLINE> 

222 Header 

223 ------ 

224 <BLANKLINE> 

225 Manufacturer : UPRTek 

226 Catalog Number : None 

227 Description : None 

228 Document Creator : None 

229 Unique Identifier : None 

230 Measurement Equipment : CV600 

231 Laboratory : None 

232 Report Number : None 

233 Report Date : 2021/01/04_23:14:46 

234 Document Creation Date : None 

235 Comments : {...} 

236 <BLANKLINE> 

237 Spectral Data 

238 ------------- 

239 <BLANKLINE> 

240 [[ 3.80000000e+02 3.02670000e-02] 

241 [ 3.90000000e+02 3.52230000e-02] 

242 [ 4.00000000e+02 1.93250000e-02] 

243 [ 4.10000000e+02 2.94260000e-02] 

244 [ 4.20000000e+02 8.76780000e-02] 

245 [ 4.30000000e+02 6.32578000e-01] 

246 [ 4.40000000e+02 3.62565900e+00] 

247 [ 4.50000000e+02 1.42069180e+01] 

248 [ 4.60000000e+02 1.70112970e+01] 

249 [ 4.70000000e+02 1.19673130e+01] 

250 [ 4.80000000e+02 8.42736200e+00] 

251 [ 4.90000000e+02 7.97729800e+00] 

252 [ 5.00000000e+02 8.71903600e+00] 

253 [ 5.10000000e+02 9.55321500e+00] 

254 [ 5.20000000e+02 9.90610500e+00] 

255 [ 5.30000000e+02 9.91394400e+00] 

256 [ 5.40000000e+02 9.74738000e+00] 

257 [ 5.50000000e+02 9.53404900e+00] 

258 [ 5.60000000e+02 9.27392200e+00] 

259 [ 5.70000000e+02 9.02323400e+00] 

260 [ 5.80000000e+02 8.91788800e+00] 

261 [ 5.90000000e+02 9.11454600e+00] 

262 [ 6.00000000e+02 9.55787100e+00] 

263 [ 6.10000000e+02 1.00600760e+01] 

264 [ 6.20000000e+02 1.04846200e+01] 

265 [ 6.30000000e+02 1.05679540e+01] 

266 [ 6.40000000e+02 1.04359870e+01] 

267 [ 6.50000000e+02 9.82122300e+00] 

268 [ 6.60000000e+02 8.77578300e+00] 

269 [ 6.70000000e+02 7.56471800e+00] 

270 [ 6.80000000e+02 6.29808600e+00] 

271 [ 6.90000000e+02 5.15623400e+00] 

272 [ 7.00000000e+02 4.05390600e+00] 

273 [ 7.10000000e+02 3.06638600e+00] 

274 [ 7.20000000e+02 2.19250000e+00] 

275 [ 7.30000000e+02 1.53922800e+00] 

276 [ 7.40000000e+02 1.14938200e+00] 

277 [ 7.50000000e+02 9.05095000e-01] 

278 [ 7.60000000e+02 6.90947000e-01] 

279 [ 7.70000000e+02 5.08426000e-01] 

280 [ 7.80000000e+02 4.11766000e-01]] 

281 """ 

282 

283 representation = super().__str__() 

284 

285 return representation.replace( 

286 ("IES TM-27-14 Spectral Distribution\n=================================="), 

287 "UPRTek\n======", 

288 ) 

289 

290 def read(self) -> SpectralDistribution_UPRTek: 

291 """ 

292 Read and parse the spectral data from the specified *UPRTek* *CSV* 

293 file. 

294 

295 Returns 

296 ------- 

297 :class:`colour.SpectralDistribution_UPRTek` 

298 *UPRTek* spectral distribution. 

299 

300 Raises 

301 ------ 

302 IOError 

303 If the file cannot be read. 

304 

305 Examples 

306 -------- 

307 >>> from os.path import dirname, join 

308 >>> from colour import SpectralShape 

309 >>> directory = join(dirname(__file__), "tests", "resources") 

310 >>> sd = SpectralDistribution_UPRTek( 

311 ... join(directory, "ESPD2021_0104_231446.xls") 

312 ... ) 

313 >>> print(sd.read().align(SpectralShape(380, 780, 10))) 

314 ... # doctest: +ELLIPSIS 

315 UPRTek 

316 ====== 

317 <BLANKLINE> 

318 Path : ... 

319 Spectral Quantity : irradiance 

320 Reflection Geometry : None 

321 Transmission Geometry : None 

322 Bandwidth (FWHM) : None 

323 Bandwidth Corrected : None 

324 <BLANKLINE> 

325 Header 

326 ------ 

327 <BLANKLINE> 

328 Manufacturer : UPRTek 

329 Catalog Number : None 

330 Description : None 

331 Document Creator : None 

332 Unique Identifier : None 

333 Measurement Equipment : CV600 

334 Laboratory : None 

335 Report Number : None 

336 Report Date : 2021/01/04_23:14:46 

337 Document Creation Date : None 

338 Comments : {...} 

339 <BLANKLINE> 

340 Spectral Data 

341 ------------- 

342 <BLANKLINE> 

343 [[ 3.80000000e+02 3.02670000e-02] 

344 [ 3.90000000e+02 3.52230000e-02] 

345 [ 4.00000000e+02 1.93250000e-02] 

346 [ 4.10000000e+02 2.94260000e-02] 

347 [ 4.20000000e+02 8.76780000e-02] 

348 [ 4.30000000e+02 6.32578000e-01] 

349 [ 4.40000000e+02 3.62565900e+00] 

350 [ 4.50000000e+02 1.42069180e+01] 

351 [ 4.60000000e+02 1.70112970e+01] 

352 [ 4.70000000e+02 1.19673130e+01] 

353 [ 4.80000000e+02 8.42736200e+00] 

354 [ 4.90000000e+02 7.97729800e+00] 

355 [ 5.00000000e+02 8.71903600e+00] 

356 [ 5.10000000e+02 9.55321500e+00] 

357 [ 5.20000000e+02 9.90610500e+00] 

358 [ 5.30000000e+02 9.91394400e+00] 

359 [ 5.40000000e+02 9.74738000e+00] 

360 [ 5.50000000e+02 9.53404900e+00] 

361 [ 5.60000000e+02 9.27392200e+00] 

362 [ 5.70000000e+02 9.02323400e+00] 

363 [ 5.80000000e+02 8.91788800e+00] 

364 [ 5.90000000e+02 9.11454600e+00] 

365 [ 6.00000000e+02 9.55787100e+00] 

366 [ 6.10000000e+02 1.00600760e+01] 

367 [ 6.20000000e+02 1.04846200e+01] 

368 [ 6.30000000e+02 1.05679540e+01] 

369 [ 6.40000000e+02 1.04359870e+01] 

370 [ 6.50000000e+02 9.82122300e+00] 

371 [ 6.60000000e+02 8.77578300e+00] 

372 [ 6.70000000e+02 7.56471800e+00] 

373 [ 6.80000000e+02 6.29808600e+00] 

374 [ 6.90000000e+02 5.15623400e+00] 

375 [ 7.00000000e+02 4.05390600e+00] 

376 [ 7.10000000e+02 3.06638600e+00] 

377 [ 7.20000000e+02 2.19250000e+00] 

378 [ 7.30000000e+02 1.53922800e+00] 

379 [ 7.40000000e+02 1.14938200e+00] 

380 [ 7.50000000e+02 9.05095000e-01] 

381 [ 7.60000000e+02 6.90947000e-01] 

382 [ 7.70000000e+02 5.08426000e-01] 

383 [ 7.80000000e+02 4.11766000e-01]] 

384 """ 

385 

386 path = cast("str", self.path) 

387 

388 def as_array(a: Any) -> list: 

389 """ 

390 Input list of numbers and converts each element to 

391 float data type. 

392 """ 

393 

394 return [as_float_scalar(e) for e in a] 

395 

396 spectral_sections = defaultdict(list) 

397 with open(path, encoding="utf-8") as csv_file: 

398 content = csv.reader(csv_file, delimiter=self._DELIMITER) 

399 

400 spectral_section = 0 

401 for row in content: 

402 if not "".join(row).strip(): 

403 continue 

404 

405 attribute, tokens = row[0], row[1:] 

406 value = tokens[0] if len(tokens) == 1 else tokens 

407 

408 if ( 

409 match := re.match(self._SPECTRAL_DATA_PATTERN, attribute) 

410 ) is not None: 

411 wavelength = match.group(1) 

412 

413 if wavelength == self._SPECTRAL_SECTION: 

414 spectral_section += 1 

415 

416 spectral_sections[spectral_section].append([wavelength, value]) 

417 else: 

418 for method in (int, float, as_array): 

419 try: 

420 self._metadata[attribute] = method( 

421 value # pyright: ignore 

422 ) 

423 except (TypeError, ValueError): # noqa: PERF203 

424 self._metadata[attribute] = value 

425 else: 

426 break 

427 

428 self.name = os.path.splitext(os.path.basename(path))[0] 

429 spectral_data = as_float_array( 

430 spectral_sections[sorted(spectral_sections.keys())[-1]] 

431 ) 

432 

433 self.wavelengths = spectral_data[..., 0] 

434 self.values = spectral_data[..., 1] 

435 

436 self.header.comments = json.dumps(self._metadata) 

437 

438 self.header.report_date = self._metadata.get("Time") 

439 self.header.measurement_equipment = self._metadata.get("Model Name") 

440 self.header.manufacturer = "UPRTek" 

441 self.spectral_quantity = "irradiance" 

442 

443 return self 

444 

445 

446class SpectralDistribution_Sekonic(SpectralDistribution_UPRTek): 

447 """ 

448 Provide support for reading and writing *IES TM-27-14* spectral data XML 

449 files from *Sekonic* *CSV* files. 

450 

451 This class extends the *UPRTek* spectral distribution functionality to 

452 handle *Sekonic* spectrometer data files. It enables conversion between 

453 *Sekonic* *CSV* format and the standardized *IES TM-27-14* XML format. 

454 

455 Parameters 

456 ---------- 

457 path 

458 Path for *Sekonic* *CSV* file. 

459 

460 Attributes 

461 ---------- 

462 - :attr:`~colour.SpectralDistribution_UPRTek.metadata` 

463 

464 Methods 

465 ------- 

466 - :meth:`~colour.SpectralDistribution_Sekonic.__init__` 

467 - :meth:`~colour.SpectralDistribution_Sekonic.__str__` 

468 - :meth:`~colour.SpectralDistribution_Sekonic.read` 

469 

470 Examples 

471 -------- 

472 >>> from os.path import dirname, join 

473 >>> from colour import SpectralShape 

474 >>> directory = join(dirname(__file__), "tests", "resources") 

475 >>> sd = SpectralDistribution_Sekonic(join(directory, "RANDOM_001_02._3262K.csv")) 

476 >>> print(sd.read().align(SpectralShape(380, 780, 10))) 

477 ... # doctest: +ELLIPSIS 

478 Sekonic 

479 ======= 

480 <BLANKLINE> 

481 Path : ... 

482 Spectral Quantity : irradiance 

483 Reflection Geometry : None 

484 Transmission Geometry : None 

485 Bandwidth (FWHM) : None 

486 Bandwidth Corrected : None 

487 <BLANKLINE> 

488 Header 

489 ------ 

490 <BLANKLINE> 

491 Manufacturer : Sekonic 

492 Catalog Number : None 

493 Description : None 

494 Document Creator : None 

495 Unique Identifier : None 

496 Measurement Equipment : None 

497 Laboratory : None 

498 Report Number : None 

499 Report Date : 15/03/2021 3:44:14 p.m. 

500 Document Creation Date : None 

501 Comments : {...} 

502 <BLANKLINE> 

503 Spectral Data 

504 ------------- 

505 <BLANKLINE> 

506 [[ 3.80000000e+02 1.69406589e-21] 

507 [ 3.90000000e+02 2.11758237e-22] 

508 [ 4.00000000e+02 1.19813650e-05] 

509 [ 4.10000000e+02 1.97110530e-05] 

510 [ 4.20000000e+02 2.99661440e-05] 

511 [ 4.30000000e+02 6.38192720e-05] 

512 [ 4.40000000e+02 1.68909683e-04] 

513 [ 4.50000000e+02 3.31902935e-04] 

514 [ 4.60000000e+02 3.33143020e-04] 

515 [ 4.70000000e+02 2.30227481e-04] 

516 [ 4.80000000e+02 1.66981976e-04] 

517 [ 4.90000000e+02 1.64439844e-04] 

518 [ 5.00000000e+02 2.01534538e-04] 

519 [ 5.10000000e+02 2.57840526e-04] 

520 [ 5.20000000e+02 3.04612651e-04] 

521 [ 5.30000000e+02 3.41368344e-04] 

522 [ 5.40000000e+02 3.63639323e-04] 

523 [ 5.50000000e+02 3.87050648e-04] 

524 [ 5.60000000e+02 4.21619130e-04] 

525 [ 5.70000000e+02 4.58150520e-04] 

526 [ 5.80000000e+02 5.01176575e-04] 

527 [ 5.90000000e+02 5.40883630e-04] 

528 [ 6.00000000e+02 5.71256795e-04] 

529 [ 6.10000000e+02 5.83703280e-04] 

530 [ 6.20000000e+02 5.57688472e-04] 

531 [ 6.30000000e+02 5.17328095e-04] 

532 [ 6.40000000e+02 4.39994939e-04] 

533 [ 6.50000000e+02 3.62766819e-04] 

534 [ 6.60000000e+02 2.96465587e-04] 

535 [ 6.70000000e+02 2.43966802e-04] 

536 [ 6.80000000e+02 2.04134776e-04] 

537 [ 6.90000000e+02 1.75304012e-04] 

538 [ 7.00000000e+02 1.52887544e-04] 

539 [ 7.10000000e+02 1.29795619e-04] 

540 [ 7.20000000e+02 1.03122693e-04] 

541 [ 7.30000000e+02 8.77607820e-05] 

542 [ 7.40000000e+02 7.61524130e-05] 

543 [ 7.50000000e+02 7.06516880e-05] 

544 [ 7.60000000e+02 3.72199210e-05] 

545 [ 7.70000000e+02 3.63058860e-05] 

546 [ 7.80000000e+02 3.55755470e-05]] 

547 >>> sd.header.comments # doctest: +SKIP 

548 >>> sd.metadata.keys() # doctest: +SKIP 

549 >>> sd.write(join(directory, "RANDOM_001_02._3262K.spdx")) 

550 ... # doctest: +SKIP 

551 """ 

552 

553 _DELIMITER: str = "," 

554 _SPECTRAL_SECTION: str = "380" 

555 _SPECTRAL_DATA_PATTERN: str = "Spectral Data (\\d{3})\\[nm\\]" 

556 

557 def __init__(self, path: str | PathLike, **kwargs: Any) -> None: 

558 super().__init__(path, **kwargs) 

559 

560 def __str__(self) -> str: 

561 """ 

562 Return a formatted string representation of the *Sekonic* spectral 

563 distribution. 

564 

565 Returns 

566 ------- 

567 :class:`str` 

568 Formatted string representation. 

569 

570 Examples 

571 -------- 

572 >>> from os.path import dirname, join 

573 >>> from colour import SpectralShape 

574 >>> directory = join(dirname(__file__), "tests", "resources") 

575 >>> sd = SpectralDistribution_UPRTek( 

576 ... join(directory, "ESPD2021_0104_231446.xls") 

577 ... ) 

578 >>> print(sd.read().align(SpectralShape(380, 780, 10))) 

579 ... # doctest: +ELLIPSIS 

580 UPRTek 

581 ====== 

582 <BLANKLINE> 

583 Path : ... 

584 Spectral Quantity : irradiance 

585 Reflection Geometry : None 

586 Transmission Geometry : None 

587 Bandwidth (FWHM) : None 

588 Bandwidth Corrected : None 

589 <BLANKLINE> 

590 Header 

591 ------ 

592 <BLANKLINE> 

593 Manufacturer : UPRTek 

594 Catalog Number : None 

595 Description : None 

596 Document Creator : None 

597 Unique Identifier : None 

598 Measurement Equipment : CV600 

599 Laboratory : None 

600 Report Number : None 

601 Report Date : 2021/01/04_23:14:46 

602 Document Creation Date : None 

603 Comments : {...} 

604 <BLANKLINE> 

605 Spectral Data 

606 ------------- 

607 <BLANKLINE> 

608 [[ 3.80000000e+02 3.02670000e-02] 

609 [ 3.90000000e+02 3.52230000e-02] 

610 [ 4.00000000e+02 1.93250000e-02] 

611 [ 4.10000000e+02 2.94260000e-02] 

612 [ 4.20000000e+02 8.76780000e-02] 

613 [ 4.30000000e+02 6.32578000e-01] 

614 [ 4.40000000e+02 3.62565900e+00] 

615 [ 4.50000000e+02 1.42069180e+01] 

616 [ 4.60000000e+02 1.70112970e+01] 

617 [ 4.70000000e+02 1.19673130e+01] 

618 [ 4.80000000e+02 8.42736200e+00] 

619 [ 4.90000000e+02 7.97729800e+00] 

620 [ 5.00000000e+02 8.71903600e+00] 

621 [ 5.10000000e+02 9.55321500e+00] 

622 [ 5.20000000e+02 9.90610500e+00] 

623 [ 5.30000000e+02 9.91394400e+00] 

624 [ 5.40000000e+02 9.74738000e+00] 

625 [ 5.50000000e+02 9.53404900e+00] 

626 [ 5.60000000e+02 9.27392200e+00] 

627 [ 5.70000000e+02 9.02323400e+00] 

628 [ 5.80000000e+02 8.91788800e+00] 

629 [ 5.90000000e+02 9.11454600e+00] 

630 [ 6.00000000e+02 9.55787100e+00] 

631 [ 6.10000000e+02 1.00600760e+01] 

632 [ 6.20000000e+02 1.04846200e+01] 

633 [ 6.30000000e+02 1.05679540e+01] 

634 [ 6.40000000e+02 1.04359870e+01] 

635 [ 6.50000000e+02 9.82122300e+00] 

636 [ 6.60000000e+02 8.77578300e+00] 

637 [ 6.70000000e+02 7.56471800e+00] 

638 [ 6.80000000e+02 6.29808600e+00] 

639 [ 6.90000000e+02 5.15623400e+00] 

640 [ 7.00000000e+02 4.05390600e+00] 

641 [ 7.10000000e+02 3.06638600e+00] 

642 [ 7.20000000e+02 2.19250000e+00] 

643 [ 7.30000000e+02 1.53922800e+00] 

644 [ 7.40000000e+02 1.14938200e+00] 

645 [ 7.50000000e+02 9.05095000e-01] 

646 [ 7.60000000e+02 6.90947000e-01] 

647 [ 7.70000000e+02 5.08426000e-01] 

648 [ 7.80000000e+02 4.11766000e-01]] 

649 """ 

650 

651 representation = super().__str__() 

652 

653 return representation.replace( 

654 "UPRTek\n======", 

655 "Sekonic\n=======", 

656 ) 

657 

658 def read(self) -> SpectralDistribution_Sekonic: 

659 """ 

660 Read and parse the spectral data from the specified *Sekonic* 

661 *Pseudo-XLS* file. 

662 

663 Returns 

664 ------- 

665 :class:`colour.SpectralDistribution_Sekonic` 

666 *Sekonic* spectral distribution. 

667 

668 Raises 

669 ------ 

670 IOError 

671 If the file cannot be read. 

672 

673 Examples 

674 -------- 

675 >>> from os.path import dirname, join 

676 >>> from colour import SpectralShape 

677 >>> directory = join(dirname(__file__), "tests", "resources") 

678 >>> sd = SpectralDistribution_Sekonic( 

679 ... join(directory, "RANDOM_001_02._3262K.csv") 

680 ... ) 

681 >>> print(sd.read().align(SpectralShape(380, 780, 10))) 

682 ... # doctest: +ELLIPSIS 

683 Sekonic 

684 ======= 

685 <BLANKLINE> 

686 Path : ... 

687 Spectral Quantity : irradiance 

688 Reflection Geometry : None 

689 Transmission Geometry : None 

690 Bandwidth (FWHM) : None 

691 Bandwidth Corrected : None 

692 <BLANKLINE> 

693 Header 

694 ------ 

695 <BLANKLINE> 

696 Manufacturer : Sekonic 

697 Catalog Number : None 

698 Description : None 

699 Document Creator : None 

700 Unique Identifier : None 

701 Measurement Equipment : None 

702 Laboratory : None 

703 Report Number : None 

704 Report Date : 15/03/2021 3:44:14 p.m. 

705 Document Creation Date : None 

706 Comments : {...} 

707 <BLANKLINE> 

708 Spectral Data 

709 ------------- 

710 <BLANKLINE> 

711 [[ 3.80000000e+02 1.69406589e-21] 

712 [ 3.90000000e+02 2.11758237e-22] 

713 [ 4.00000000e+02 1.19813650e-05] 

714 [ 4.10000000e+02 1.97110530e-05] 

715 [ 4.20000000e+02 2.99661440e-05] 

716 [ 4.30000000e+02 6.38192720e-05] 

717 [ 4.40000000e+02 1.68909683e-04] 

718 [ 4.50000000e+02 3.31902935e-04] 

719 [ 4.60000000e+02 3.33143020e-04] 

720 [ 4.70000000e+02 2.30227481e-04] 

721 [ 4.80000000e+02 1.66981976e-04] 

722 [ 4.90000000e+02 1.64439844e-04] 

723 [ 5.00000000e+02 2.01534538e-04] 

724 [ 5.10000000e+02 2.57840526e-04] 

725 [ 5.20000000e+02 3.04612651e-04] 

726 [ 5.30000000e+02 3.41368344e-04] 

727 [ 5.40000000e+02 3.63639323e-04] 

728 [ 5.50000000e+02 3.87050648e-04] 

729 [ 5.60000000e+02 4.21619130e-04] 

730 [ 5.70000000e+02 4.58150520e-04] 

731 [ 5.80000000e+02 5.01176575e-04] 

732 [ 5.90000000e+02 5.40883630e-04] 

733 [ 6.00000000e+02 5.71256795e-04] 

734 [ 6.10000000e+02 5.83703280e-04] 

735 [ 6.20000000e+02 5.57688472e-04] 

736 [ 6.30000000e+02 5.17328095e-04] 

737 [ 6.40000000e+02 4.39994939e-04] 

738 [ 6.50000000e+02 3.62766819e-04] 

739 [ 6.60000000e+02 2.96465587e-04] 

740 [ 6.70000000e+02 2.43966802e-04] 

741 [ 6.80000000e+02 2.04134776e-04] 

742 [ 6.90000000e+02 1.75304012e-04] 

743 [ 7.00000000e+02 1.52887544e-04] 

744 [ 7.10000000e+02 1.29795619e-04] 

745 [ 7.20000000e+02 1.03122693e-04] 

746 [ 7.30000000e+02 8.77607820e-05] 

747 [ 7.40000000e+02 7.61524130e-05] 

748 [ 7.50000000e+02 7.06516880e-05] 

749 [ 7.60000000e+02 3.72199210e-05] 

750 [ 7.70000000e+02 3.63058860e-05] 

751 [ 7.80000000e+02 3.55755470e-05]] 

752 """ 

753 

754 super().read() 

755 

756 self.header.report_date = self._metadata.get("Date Saved") 

757 self.header.manufacturer = "Sekonic" 

758 

759 return self