skinoptics 0.0.1b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,402 @@
1
+ '''
2
+ | SkinOptics
3
+ | Copyright (C) 2024 Victor Lima
4
+
5
+ | This program is free software: you can redistribute it and/or modify
6
+ | it under the terms of the GNU General Public License as published by
7
+ | the Free Software Foundation, either version 3 of the License, or
8
+ | (at your option) any later version.
9
+
10
+ | This program is distributed in the hope that it will be useful,
11
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ | GNU General Public License for more details.
14
+
15
+ | You should have received a copy of the GNU General Public License
16
+ | along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ | Victor Lima
19
+ | victorporto\@ifsc.usp.br
20
+ | victor.lima\@ufscar.br
21
+
22
+ | Release Date:
23
+ | October 2024
24
+ | Last Modification:
25
+ | October 2024
26
+
27
+ | References:
28
+
29
+ | [SJT95] Saidi, Jacques & Tittel 1995.
30
+ | Mie and Rayleigh modeling of visible-light scattering in neonatal skin.
31
+ | https://doi.org/10.1364/AO.34.007410
32
+
33
+ | [S*06] Salomatina, Jiang, Novak & Yaroslavsky 2006.
34
+ | Optical properties of normal and cancerous human skin in the visible and near-infrared spectral range.
35
+ | https://doi.org/10.1117/1.2398928
36
+
37
+ | [J13] Jacques 2013.
38
+ | Optical properties of biological tissues: a review.
39
+ | https://doi.org/10.1088/0031-9155/58/14/5007
40
+
41
+ | [N19] Niemz 2019.
42
+ | Laser-Tissue Interactions: Fundamentals and Applications (4th edition).
43
+ | https://doi.org/10.1007/978-3-030-11917-1
44
+ '''
45
+
46
+ import numpy as np
47
+ from scipy.interpolate import interp1d
48
+
49
+ from skinoptics.utils import *
50
+ from skinoptics.dataframes import *
51
+
52
+ def albedo(mua, mus):
53
+ r'''
54
+ | Calculate the optical albedo from the absorption coefficient and the scattering coefficient.
55
+ | For details please check section 2.4 from Niemz 2019 [N19].
56
+
57
+ :math:`a = \frac{\mu_s}{\mu_a + \mu_s}`
58
+
59
+ :param mua: absorption coefficient [mm^-1]
60
+ :type mua: float or np.ndarray
61
+
62
+ :param mus: scattering coefficient [mm^-1]
63
+ :type mus: float or np.ndarray
64
+
65
+ :return: - **albedo** (*float or np.ndarray*) – optical albedo [-]
66
+ '''
67
+
68
+ return mus/(mua + mus)
69
+
70
+ def mus_from_rmus(rmus, g):
71
+ r'''
72
+ | Calculate the scattering coefficient from the reduced scattering coefficient and the
73
+ | anisotropy factor.
74
+
75
+ :math:`\mu_s(\lambda) = \frac{\mu_s'(\lambda)}{1-g}`
76
+
77
+ :param rmus: reduced scattering coefficient [mm^-1]
78
+ :type rmus: float or np.ndarray
79
+
80
+ :param g: anisotropy factor [-] (must be in the range [-1, 1])
81
+ :type g: float
82
+
83
+ :return: - **mus** (*float or np.ndarray*) – scattering coefficient [mm^-1]
84
+ '''
85
+
86
+ return rmus/(1 - g)
87
+
88
+ def rmus_from_mus(mus, g):
89
+ r'''
90
+ | Calculate the reduced scattering coefficient from the scattering coefficient and the
91
+ | anisotropy factor.
92
+
93
+ :math:`\mu_s'(\lambda) = (1-g) \mbox{ } \mu_s(\lambda)`
94
+
95
+ :param mus: scattering coefficient [mm^-1]
96
+ :type mus: float or np.ndarray
97
+
98
+ :param g: anisotropy factor [-] (must be in the range [-1, 1])
99
+ :type g: float
100
+
101
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
102
+ '''
103
+
104
+ return mus*(1 - g)
105
+
106
+ def rmus_EP_Salomatina(lambda0):
107
+ r'''
108
+ | The reduced scattering coefficient of human EPIDERMIS as a function of wavelength.
109
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
110
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2>.
111
+
112
+ | wavelength range: [370 nm, 1600 nm]
113
+
114
+ :param lambda0: wavelength [nm]
115
+ :type lambda0: float or np.ndarray
116
+
117
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
118
+ '''
119
+
120
+ return interp1d(np.array(EP_Salomatina_dataframe)[:,0],
121
+ np.array(EP_Salomatina_dataframe)[:,3],
122
+ bounds_error = False,
123
+ fill_value = (np.array(EP_Salomatina_dataframe)[0,3],
124
+ np.array(EP_Salomatina_dataframe)[-1,3]))(lambda0)
125
+
126
+ def rmus_DE_Salomatina(lambda0):
127
+ r'''
128
+ | The reduced scattering coefficient of human DERMIS as a function of wavelength.
129
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
130
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2/>.
131
+
132
+ | wavelength range: [370 nm, 1600 nm]
133
+
134
+ :param lambda0: wavelength [nm]
135
+ :type lambda0: float or np.ndarray
136
+
137
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
138
+ '''
139
+
140
+ return interp1d(np.array(DE_Salomatina_dataframe)[:,0],
141
+ np.array(DE_Salomatina_dataframe)[:,3],
142
+ bounds_error = False,
143
+ fill_value = (np.array(DE_Salomatina_dataframe)[0,3],
144
+ np.array(DE_Salomatina_dataframe)[-1,3]))(lambda0)
145
+
146
+ def rmus_HY_Salomatina(lambda0):
147
+ r'''
148
+ | The reduced scattering coefficient of human HYPODERMIS as a function of wavelength.
149
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
150
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2/>.
151
+
152
+ | wavelength range: [370 nm, 1600 nm]
153
+
154
+ :param lambda0: wavelength [nm]
155
+ :type lambda0: float or np.ndarray
156
+
157
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
158
+ '''
159
+
160
+ return interp1d(np.array(HY_Salomatina_dataframe)[:,0],
161
+ np.array(HY_Salomatina_dataframe)[:,3],
162
+ bounds_error = False,
163
+ fill_value = (np.array(HY_Salomatina_dataframe)[0,3],
164
+ np.array(HY_Salomatina_dataframe)[-1,3]))(lambda0)
165
+
166
+ def rmus_iBCC_Salomatina(lambda0):
167
+ r'''
168
+ | The reduced scattering coefficient of INFILTRATIVE BASAL CELL CARCINOMA (iBCC)
169
+ | as a function of wavelength.
170
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
171
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2>.
172
+
173
+ | wavelength range: [370 nm, 1600 nm]
174
+
175
+ :param lambda0: wavelength [nm]
176
+ :type lambda0: float or np.ndarray
177
+
178
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
179
+ '''
180
+
181
+ return interp1d(np.array(iBCC_Salomatina_dataframe)[:,0],
182
+ np.array(iBCC_Salomatina_dataframe)[:,3],
183
+ bounds_error = False,
184
+ fill_value = (np.array(iBCC_Salomatina_dataframe)[0,3],
185
+ np.array(iBCC_Salomatina_dataframe)[-1,3]))(lambda0)
186
+
187
+ def rmus_nBCC_Salomatina(lambda0):
188
+ r'''
189
+ | The reduced scattering coefficient of NODULAR BASAL CELL CARCINOMA (nBCC)
190
+ | as a function of wavelength.
191
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
192
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2>.
193
+
194
+ | wavelength range: [370 nm, 1600 nm]
195
+
196
+ :param lambda0: wavelength [nm]
197
+ :type lambda0: float or np.ndarray
198
+
199
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
200
+ '''
201
+
202
+ return interp1d(np.array(nBCC_Salomatina_dataframe)[:,0],
203
+ np.array(nBCC_Salomatina_dataframe)[:,3],
204
+ bounds_error = False,
205
+ fill_value = (np.array(nBCC_Salomatina_dataframe)[0,3],
206
+ np.array(nBCC_Salomatina_dataframe)[-1,3]))(lambda0)
207
+
208
+ def rmus_SCC_Salomatina(lambda0):
209
+ r'''
210
+ | The reduced scattering coefficient of SQUAMOUS CELL CARCINOMA (SCC)
211
+ | as a function of wavelength.
212
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
213
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2>.
214
+
215
+ | wavelength range: [370 nm, 1600 nm]
216
+
217
+ :param lambda0: wavelength [nm]
218
+ :type lambda0: float or np.ndarray
219
+
220
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
221
+ '''
222
+
223
+ return interp1d(np.array(SCC_Salomatina_dataframe)[:,0],
224
+ np.array(SCC_Salomatina_dataframe)[:,3],
225
+ bounds_error = False,
226
+ fill_value = (np.array(SCC_Salomatina_dataframe)[0,3],
227
+ np.array(SCC_Salomatina_dataframe)[-1,3]))(lambda0)
228
+
229
+ def std_rmus_EP_Salomatina(lambda0):
230
+ r'''
231
+ | The standard deviation respective to :meth:`skinoptics.scattering_coefficient.rmus_EP_Salomatina`.
232
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
233
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2>.
234
+
235
+ | wavelength range: [370 nm, 1600 nm]
236
+
237
+ :param lambda0: wavelength [nm]
238
+ :type lambda0: float or np.ndarray
239
+
240
+ :return: - **std_rmus** (*float or np.ndarray*) – standard deviation of the reduced scattering coefficient [mm^-1]
241
+ '''
242
+
243
+ return interp1d(np.array(EP_Salomatina_dataframe)[:,0],
244
+ np.array(EP_Salomatina_dataframe)[:,4],
245
+ bounds_error = False,
246
+ fill_value = (np.array(EP_Salomatina_dataframe)[0,4],
247
+ np.array(EP_Salomatina_dataframe)[-1,4]))(lambda0)
248
+
249
+ def std_rmus_DE_Salomatina(lambda0):
250
+ r'''
251
+ | The standard deviation respective to :meth:`skinoptics.scattering_coefficient.rmus_DE_Salomatina`.
252
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
253
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2>.
254
+
255
+ | wavelength range: [370 nm, 1600 nm]
256
+
257
+ :param lambda0: wavelength [nm]
258
+ :type lambda0: float or np.ndarray
259
+
260
+ :return: - **std_rmus** (*float or np.ndarray*) – standard deviation of the reduced scattering coefficient [mm^-1]
261
+ '''
262
+
263
+ return interp1d(np.array(DE_Salomatina_dataframe)[:,0],
264
+ np.array(DE_Salomatina_dataframe)[:,4],
265
+ bounds_error = False,
266
+ fill_value = (np.array(DE_Salomatina_dataframe)[0,4],
267
+ np.array(DE_Salomatina_dataframe)[-1,4]))(lambda0)
268
+
269
+ def std_rmus_HY_Salomatina(lambda0):
270
+ r'''
271
+ | The standard deviation respective to :meth:`skinoptics.scattering_coefficient.rmus_HY_Salomatina`.
272
+ | Linear interpolation of experimental data from Salomatina et al. 2006 [S*06],
273
+ | publicly available at <https://sites.uml.edu/abl/optical-properties-2>.
274
+
275
+ | wavelength range: [370 nm, 1600 nm]
276
+
277
+ :param lambda0: wavelength [nm]
278
+ :type lambda0: float or np.ndarray
279
+
280
+ :return: - **std_rmus** (*float or np.ndarray*) – standard deviation of the reduced scattering coefficient [mm^-1]
281
+ '''
282
+
283
+ return interp1d(np.array(HY_Salomatina_dataframe)[:,0],
284
+ np.array(HY_Salomatina_dataframe)[:,4],
285
+ bounds_error = False,
286
+ fill_value = (np.array(HY_Salomatina_dataframe)[0,4],
287
+ np.array(HY_Salomatina_dataframe)[-1,4]))(lambda0)
288
+
289
+ def rmus_Ray(lambda0, A):
290
+ r'''
291
+ | The reduced scattering coefficient as a function of wavelength, Rayleigh scattering only.
292
+ | For details please check Jacques 2013 [J13].
293
+
294
+ :math:`\mu_s'(\lambda) = A \mbox{ } \lambda^{-4}`
295
+
296
+ :param lambda0: wavelength [nm]
297
+ :type lambda0: float or np.ndarray
298
+
299
+ :param A: parameter :math:`A` [mm^-1 nm^4] (must be nonnegative)
300
+ :type A: float
301
+
302
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
303
+ '''
304
+
305
+ if A < 0:
306
+ msg = 'The input A = {} is not valid.'.format(A)
307
+ raise Exception(msg)
308
+
309
+ return A*np.power(lambda0, -4, dtype = 'float64')
310
+
311
+ def rmus_Mie(lambda0, B, b):
312
+ r'''
313
+ | The reduced scattering coefficient as a function of wavelength, Mie scattering only.
314
+ | For details please check Jacques 2013 [J13].
315
+
316
+ :math:`\mu_s'(\lambda) = B \mbox{ } \lambda^{-b}`
317
+
318
+ :param lambda0: wavelength [nm]
319
+ :type lambda0: float or np.ndarray
320
+
321
+ :param B: parameter :math:`B` [mm^-1 nm^b] (must be nonnegative)
322
+ :type B: float
323
+
324
+ :param b: Mie scattering power [-] (must be nonnegative)
325
+ :type b: float
326
+
327
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
328
+ '''
329
+
330
+ if B < 0:
331
+ msg = 'The input B = {} is not valid.'.format(B)
332
+ raise Exception(msg)
333
+ if b < 0:
334
+ msg = 'The input b = {} is not valid.'.format(b)
335
+ raise Exception(msg)
336
+
337
+ return B*np.power(lambda0, -b, dtype = 'float64')
338
+
339
+ def rmus_Jacques(lambda0, a, f_Ray, b_Mie):
340
+ r'''
341
+ | The reduced scattering coefficient as a function of wavelength, assuming contributions from
342
+ | both Rayleigh and Mie scattering.
343
+ | For details please check Jacques 2013 [J13].
344
+
345
+ :math:`\mu_s'(\lambda) = a\left[f_{Ray} \mbox{ } \left(\frac{\lambda}{500}\right)^{-4} + (1-f_{Ray})\left(\frac{\lambda}{500}\right)^{-b_{Mie}} \right]`
346
+
347
+ :param lambda0: wavelength [nm]
348
+ :type lambda0: float or np.ndarray
349
+
350
+ :param a: parameter :math:`a` [mm^-1]
351
+ :type a: float
352
+
353
+ :param f_Ray: fraction of Rayleigh scattering contribution [-] (must be in the range [0, 1])
354
+ :type f_Ray: float
355
+
356
+ :param b_Mie: Mie scattering power [-] (must be nonnegative)
357
+ :type b_Mie: float
358
+
359
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
360
+ '''
361
+
362
+ if f_Ray < 0 or f_Ray > 1:
363
+ msg = 'The input f_Ray = {} is not valid.'.format(f_Ray)
364
+ raise Exception(msg)
365
+ if b_Mie < 0:
366
+ msg = 'The input b_Mie = {} is not valid.'.format(b_Mie)
367
+ raise Exception(msg)
368
+
369
+ return a*(rmus_Ray(lambda0 = lambda0/500., A = f_Ray) +
370
+ rmus_Mie(lambda0 = lambda0/500., B = (1 - f_Ray), b = b_Mie))
371
+
372
+ def rmus_Saidi(lambda0, A_Mie, B_Ray):
373
+ r'''
374
+ | The reduced scattering coefficient of NEONATAL SKIN as a function of wavelength.
375
+ | Saidi, Jacques & Tittel 1995 [SJT95] fit to their own experimental data.
376
+
377
+ :math:`\mu_s'(\lambda) = A_{Mie} \mbox{ (} 9.843 \times 10^{-7} \times \lambda^2 - 1.745 \times 10^{-3} \times \lambda + 1) + B_{Ray} \mbox{ } \lambda^{-4}`
378
+
379
+ | wavelength range: [450 nm, 750 nm]
380
+ | gestational ages between 19 and 52 weeks
381
+
382
+ :param lambda0: wavelength [nm]
383
+ :type lambda0: float or np.ndarray
384
+
385
+ :param A_Mie: parameter :math:`A_{Mie}` [mm^-1] (must be nonnegative)
386
+ :type A_Mie: float
387
+
388
+ :param B_Ray: parameter :math:`B_{Ray}` [mm^-1 nm^4] (must be nonnegative)
389
+ :type B_Ray: float
390
+
391
+ :return: - **rmus** (*float or np.ndarray*) – reduced scattering coefficient [mm^-1]
392
+ '''
393
+
394
+ if A_Mie < 0:
395
+ msg = 'The input A_Mie = {} is not valid.'.format(A_Mie)
396
+ raise Exception(msg)
397
+ if B_Ray < 0:
398
+ msg = 'The input B_Ray = {} is not valid.'.format(B_Ray)
399
+ raise Exception(msg)
400
+
401
+ return A_Mie*quadratic(x = lambda0, a = 9.843E-7, b = -1.745E-3, c = 1) + \
402
+ rmus_Ray(lambda0 = lambda0, A = B_Ray)