AeroViz 0.1.3__py3-none-any.whl → 0.1.3b0__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.
Potentially problematic release.
This version of AeroViz might be problematic. Click here for more details.
- AeroViz/__init__.py +4 -4
- AeroViz/dataProcess/Chemistry/__init__.py +38 -38
- AeroViz/dataProcess/Chemistry/_calculate.py +15 -15
- AeroViz/dataProcess/Chemistry/_isoropia.py +69 -68
- AeroViz/dataProcess/Chemistry/_mass_volume.py +158 -158
- AeroViz/dataProcess/Chemistry/_ocec.py +109 -109
- AeroViz/dataProcess/Chemistry/_partition.py +19 -18
- AeroViz/dataProcess/Chemistry/_teom.py +8 -11
- AeroViz/dataProcess/Optical/_IMPROVE.py +40 -39
- AeroViz/dataProcess/Optical/__init__.py +35 -35
- AeroViz/dataProcess/Optical/_absorption.py +35 -35
- AeroViz/dataProcess/Optical/_extinction.py +25 -24
- AeroViz/dataProcess/Optical/_mie.py +5 -6
- AeroViz/dataProcess/Optical/_mie_sd.py +89 -90
- AeroViz/dataProcess/Optical/_scattering.py +16 -16
- AeroViz/dataProcess/SizeDistr/__init__.py +37 -37
- AeroViz/dataProcess/SizeDistr/__merge.py +159 -158
- AeroViz/dataProcess/SizeDistr/_merge.py +155 -154
- AeroViz/dataProcess/SizeDistr/_merge_v1.py +162 -161
- AeroViz/dataProcess/SizeDistr/_merge_v2.py +153 -152
- AeroViz/dataProcess/SizeDistr/_merge_v3.py +326 -326
- AeroViz/dataProcess/SizeDistr/_merge_v4.py +272 -274
- AeroViz/dataProcess/SizeDistr/_size_distr.py +51 -51
- AeroViz/dataProcess/VOC/__init__.py +7 -7
- AeroViz/dataProcess/VOC/_potential_par.py +53 -55
- AeroViz/dataProcess/__init__.py +4 -4
- AeroViz/dataProcess/core/__init__.py +59 -58
- AeroViz/plot/__init__.py +6 -1
- AeroViz/plot/bar.py +126 -0
- AeroViz/plot/box.py +68 -0
- AeroViz/plot/distribution/distribution.py +421 -427
- AeroViz/plot/meteorology/meteorology.py +240 -292
- AeroViz/plot/optical/__init__.py +0 -1
- AeroViz/plot/optical/optical.py +230 -230
- AeroViz/plot/pie.py +198 -0
- AeroViz/plot/regression.py +210 -0
- AeroViz/plot/scatter.py +99 -0
- AeroViz/plot/templates/__init__.py +0 -3
- AeroViz/plot/templates/contour.py +25 -25
- AeroViz/plot/templates/corr_matrix.py +86 -93
- AeroViz/plot/templates/diurnal_pattern.py +24 -24
- AeroViz/plot/templates/koschmieder.py +106 -106
- AeroViz/plot/templates/metal_heatmap.py +34 -34
- AeroViz/plot/timeseries/timeseries.py +53 -60
- AeroViz/plot/utils/__init__.py +2 -1
- AeroViz/plot/utils/_color.py +57 -57
- AeroViz/plot/utils/_unit.py +48 -48
- AeroViz/plot/utils/plt_utils.py +92 -0
- AeroViz/plot/utils/sklearn_utils.py +49 -0
- AeroViz/plot/violin.py +79 -0
- AeroViz/process/__init__.py +15 -15
- AeroViz/process/core/DataProc.py +9 -9
- AeroViz/process/core/SizeDist.py +81 -81
- AeroViz/process/method/PyMieScatt_update.py +488 -488
- AeroViz/process/method/mie_theory.py +231 -229
- AeroViz/process/method/prop.py +40 -40
- AeroViz/process/script/AbstractDistCalc.py +103 -103
- AeroViz/process/script/Chemical.py +166 -166
- AeroViz/process/script/IMPACT.py +40 -40
- AeroViz/process/script/IMPROVE.py +152 -152
- AeroViz/process/script/Others.py +45 -45
- AeroViz/process/script/PSD.py +26 -26
- AeroViz/process/script/PSD_dry.py +69 -70
- AeroViz/process/script/retrieve_RI.py +50 -51
- AeroViz/rawDataReader/__init__.py +57 -57
- AeroViz/rawDataReader/core/__init__.py +328 -326
- AeroViz/rawDataReader/script/AE33.py +18 -18
- AeroViz/rawDataReader/script/AE43.py +20 -20
- AeroViz/rawDataReader/script/APS_3321.py +30 -30
- AeroViz/rawDataReader/script/Aurora.py +23 -23
- AeroViz/rawDataReader/script/BC1054.py +40 -40
- AeroViz/rawDataReader/script/EPA_vertical.py +9 -9
- AeroViz/rawDataReader/script/GRIMM.py +21 -21
- AeroViz/rawDataReader/script/IGAC_TH.py +67 -67
- AeroViz/rawDataReader/script/IGAC_ZM.py +59 -59
- AeroViz/rawDataReader/script/MA350.py +39 -39
- AeroViz/rawDataReader/script/NEPH.py +74 -74
- AeroViz/rawDataReader/script/OCEC_LCRES.py +21 -21
- AeroViz/rawDataReader/script/OCEC_RES.py +16 -16
- AeroViz/rawDataReader/script/SMPS_TH.py +25 -25
- AeroViz/rawDataReader/script/SMPS_aim11.py +32 -32
- AeroViz/rawDataReader/script/SMPS_genr.py +31 -31
- AeroViz/rawDataReader/script/TEOM.py +28 -28
- AeroViz/rawDataReader/script/Table.py +12 -12
- AeroViz/rawDataReader/script/VOC_TH.py +16 -16
- AeroViz/rawDataReader/script/VOC_ZM.py +28 -28
- AeroViz/rawDataReader/script/__init__.py +20 -20
- AeroViz/rawDataReader/utils/config.py +161 -161
- AeroViz/tools/database.py +65 -65
- AeroViz/tools/dataclassifier.py +106 -106
- AeroViz/tools/dataprinter.py +51 -51
- AeroViz/tools/datareader.py +38 -38
- {AeroViz-0.1.3.dist-info → AeroViz-0.1.3b0.dist-info}/METADATA +5 -4
- AeroViz-0.1.3b0.dist-info/RECORD +110 -0
- AeroViz/config/__init__.py +0 -0
- AeroViz/plot/improve/__init__.py +0 -1
- AeroViz/plot/improve/improve.py +0 -240
- AeroViz/plot/optical/aethalometer.py +0 -77
- AeroViz/plot/templates/event_evolution.py +0 -65
- AeroViz/plot/templates/regression.py +0 -256
- AeroViz/plot/templates/scatter.py +0 -130
- AeroViz/plot/templates/templates.py +0 -398
- AeroViz/plot/utils/_decorator.py +0 -74
- AeroViz-0.1.3.dist-info/RECORD +0 -111
- {AeroViz-0.1.3.dist-info → AeroViz-0.1.3b0.dist-info}/LICENSE +0 -0
- {AeroViz-0.1.3.dist-info → AeroViz-0.1.3b0.dist-info}/WHEEL +0 -0
- {AeroViz-0.1.3.dist-info → AeroViz-0.1.3b0.dist-info}/top_level.txt +0 -0
|
@@ -2,257 +2,259 @@ from typing import Sequence, Literal
|
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
import pandas as pd
|
|
5
|
-
from .PyMieScatt_update import AutoMieQ
|
|
6
5
|
from numpy import exp, log, log10, sqrt, pi
|
|
7
6
|
|
|
7
|
+
from .PyMieScatt_update import AutoMieQ
|
|
8
|
+
|
|
8
9
|
|
|
9
10
|
def Mie_Q(m: complex,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
11
|
+
wavelength: float,
|
|
12
|
+
dp: float | Sequence[float]
|
|
13
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
14
|
+
"""
|
|
15
|
+
Calculate Mie scattering efficiency (Q) for given spherical particle diameter(s).
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
m : complex
|
|
20
|
+
The complex refractive index of the particles.
|
|
21
|
+
wavelength : float
|
|
22
|
+
The wavelength of the incident light (in nm).
|
|
23
|
+
dp : float | Sequence[float]
|
|
24
|
+
Particle diameters (in nm), can be a single value or Sequence object.
|
|
25
|
+
|
|
26
|
+
Returns
|
|
27
|
+
-------
|
|
28
|
+
Q_ext : ndarray
|
|
29
|
+
The Mie extinction efficiency for each particle diameter.
|
|
30
|
+
Q_sca : ndarray
|
|
31
|
+
The Mie scattering efficiency for each particle diameter.
|
|
32
|
+
Q_abs : ndarray
|
|
33
|
+
The Mie absorption efficiency for each particle diameter.
|
|
34
|
+
|
|
35
|
+
Examples
|
|
36
|
+
--------
|
|
37
|
+
>>> Q_ext, Q_sca, Q_abs = Mie_Q(m=complex(1.5, 0.02), wavelength=550, dp=[100, 200, 300, 400])
|
|
38
|
+
"""
|
|
39
|
+
# Ensure dp is a numpy array
|
|
40
|
+
dp = np.atleast_1d(dp)
|
|
41
|
+
|
|
42
|
+
# Transpose for proper unpacking
|
|
43
|
+
Q_ext, Q_sca, Q_abs, g, Q_pr, Q_back, Q_ratio = np.array([AutoMieQ(m, wavelength, _dp) for _dp in dp]).T
|
|
44
|
+
|
|
45
|
+
return Q_ext, Q_sca, Q_abs
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
def Mie_MEE(m: complex,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
49
|
+
wavelength: float,
|
|
50
|
+
dp: float | Sequence[float],
|
|
51
|
+
density: float
|
|
52
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
53
|
+
"""
|
|
54
|
+
Calculate mass extinction efficiency and other parameters.
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
m : complex
|
|
59
|
+
The complex refractive index of the particles.
|
|
60
|
+
wavelength : float
|
|
61
|
+
The wavelength of the incident light.
|
|
62
|
+
dp : float | Sequence[float]
|
|
63
|
+
List of particle sizes or a single value.
|
|
64
|
+
density : float
|
|
65
|
+
The density of particles.
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
MEE : ndarray
|
|
70
|
+
The mass extinction efficiency for each particle diameter.
|
|
71
|
+
MSE : ndarray
|
|
72
|
+
The mass scattering efficiency for each particle diameter.
|
|
73
|
+
MAE : ndarray
|
|
74
|
+
The mass absorption efficiency for each particle diameter.
|
|
75
|
+
|
|
76
|
+
Examples
|
|
77
|
+
--------
|
|
78
|
+
>>> MEE, MSE, MAE = Mie_MEE(m=complex(1.5, 0.02), wavelength=550, dp=[100, 200, 300, 400], density=1.2)
|
|
79
|
+
"""
|
|
80
|
+
Q_ext, Q_sca, Q_abs = Mie_Q(m, wavelength, dp)
|
|
81
|
+
|
|
82
|
+
MEE = (3 * Q_ext) / (2 * density * dp) * 1000
|
|
83
|
+
MSE = (3 * Q_sca) / (2 * density * dp) * 1000
|
|
84
|
+
MAE = (3 * Q_abs) / (2 * density * dp) * 1000
|
|
85
|
+
|
|
86
|
+
return MEE, MSE, MAE
|
|
86
87
|
|
|
87
88
|
|
|
88
89
|
def Mie_PESD(m: complex,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
90
|
+
wavelength: float = 550,
|
|
91
|
+
dp: float | Sequence[float] = None,
|
|
92
|
+
ndp: float | Sequence[float] = None,
|
|
93
|
+
lognormal: bool = False,
|
|
94
|
+
dp_range: tuple = (1, 2500),
|
|
95
|
+
geoMean: float = 200,
|
|
96
|
+
geoStdDev: float = 2,
|
|
97
|
+
numberOfParticles: float = 1e6,
|
|
98
|
+
numberOfBins: int = 167,
|
|
99
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
100
|
+
"""
|
|
101
|
+
Simultaneously calculate "extinction distribution" and "integrated results" using the Mie_Q method.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
m : complex
|
|
106
|
+
The complex refractive index of the particles.
|
|
107
|
+
wavelength : float
|
|
108
|
+
The wavelength of the incident light.
|
|
109
|
+
dp : float | Sequence[float]
|
|
110
|
+
Particle sizes.
|
|
111
|
+
ndp : float | Sequence[float]
|
|
112
|
+
Number concentration from SMPS or APS in the units of dN/dlogdp.
|
|
113
|
+
lognormal : bool, optional
|
|
114
|
+
Whether to use lognormal distribution for ndp. Default is False.
|
|
115
|
+
dp_range : tuple, optional
|
|
116
|
+
Range of particle sizes. Default is (1, 2500) nm.
|
|
117
|
+
geoMean : float, optional
|
|
118
|
+
Geometric mean of the particle size distribution. Default is 200 nm.
|
|
119
|
+
geoStdDev : float, optional
|
|
120
|
+
Geometric standard deviation of the particle size distribution. Default is 2.
|
|
121
|
+
numberOfParticles : float, optional
|
|
122
|
+
Number of particles. Default is 1e6.
|
|
123
|
+
numberOfBins : int, optional
|
|
124
|
+
Number of bins for the lognormal distribution. Default is 167.
|
|
125
|
+
|
|
126
|
+
Returns
|
|
127
|
+
-------
|
|
128
|
+
ext_dist : ndarray
|
|
129
|
+
The extinction distribution for the given data.
|
|
130
|
+
sca_dist : ndarray
|
|
131
|
+
The scattering distribution for the given data.
|
|
132
|
+
abs_dist : ndarray
|
|
133
|
+
The absorption distribution for the given data.
|
|
134
|
+
|
|
135
|
+
Notes
|
|
136
|
+
-----
|
|
137
|
+
return in "dext/dlogdp", please make sure input the dNdlogdp data.
|
|
138
|
+
|
|
139
|
+
Examples
|
|
140
|
+
--------
|
|
141
|
+
>>> Ext, Sca, Abs = Mie_PESD(m=complex(1.5, 0.02), wavelength=550, dp=[100, 200, 500, 1000], ndp=[100, 50, 30, 20])
|
|
142
|
+
"""
|
|
143
|
+
if lognormal:
|
|
144
|
+
dp = np.logspace(log10(dp_range[0]), log10(dp_range[1]), numberOfBins)
|
|
145
|
+
|
|
146
|
+
ndp = numberOfParticles * (1 / (log(geoStdDev) * sqrt(2 * pi)) *
|
|
147
|
+
exp(-(log(dp) - log(geoMean)) ** 2 / (2 * log(geoStdDev) ** 2)))
|
|
148
|
+
|
|
149
|
+
# dN / dlogdp
|
|
150
|
+
ndp = np.atleast_1d(ndp)
|
|
151
|
+
|
|
152
|
+
Q_ext, Q_sca, Q_abs = Mie_Q(m, wavelength, dp)
|
|
153
|
+
|
|
154
|
+
# The 1e-6 here is so that the final value is the same as the unit 1/10^6m.
|
|
155
|
+
Ext = Q_ext * (pi / 4 * dp ** 2) * ndp * 1e-6
|
|
156
|
+
Sca = Q_sca * (pi / 4 * dp ** 2) * ndp * 1e-6
|
|
157
|
+
Abs = Q_abs * (pi / 4 * dp ** 2) * ndp * 1e-6
|
|
158
|
+
|
|
159
|
+
return Ext, Sca, Abs
|
|
159
160
|
|
|
160
161
|
|
|
161
162
|
def internal(dist: pd.Series,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
163
|
+
dp: float | Sequence[float],
|
|
164
|
+
wavelength: float = 550,
|
|
165
|
+
result_type: Literal['extinction', 'scattering', 'absorption'] = 'extinction'
|
|
166
|
+
) -> np.ndarray:
|
|
167
|
+
"""
|
|
168
|
+
Calculate the extinction distribution by internal mixing model.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
----------
|
|
172
|
+
dist : pd.Series
|
|
173
|
+
Particle size distribution data.
|
|
174
|
+
dp : float | Sequence[float]
|
|
175
|
+
Diameter(s) of the particles, either a single value or a sequence.
|
|
176
|
+
wavelength : float, optional
|
|
177
|
+
Wavelength of the incident light, default is 550 nm.
|
|
178
|
+
result_type : {'extinction', 'scattering', 'absorption'}, optional
|
|
179
|
+
Type of result to calculate, defaults to 'extinction'.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
np.ndarray
|
|
184
|
+
Extinction distribution calculated based on the internal mixing model.
|
|
185
|
+
"""
|
|
186
|
+
ext_dist, sca_dist, abs_dist = Mie_PESD(m=complex(dist['n_amb'], dist['k_amb']),
|
|
187
|
+
wavelength=wavelength,
|
|
188
|
+
dp=dp,
|
|
189
|
+
ndp=np.array(dist[:np.size(dp)]))
|
|
190
|
+
|
|
191
|
+
if result_type == 'extinction':
|
|
192
|
+
return ext_dist
|
|
193
|
+
elif result_type == 'scattering':
|
|
194
|
+
return sca_dist
|
|
195
|
+
else:
|
|
196
|
+
return abs_dist
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
# return dict(ext=ext_dist, sca=sca_dist, abs=abs_dist)
|
|
198
200
|
|
|
199
201
|
|
|
200
202
|
def external(dist: pd.Series,
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
203
|
+
dp: float | Sequence[float],
|
|
204
|
+
wavelength: float = 550,
|
|
205
|
+
result_type: Literal['extinction', 'scattering', 'absorption'] = 'extinction'
|
|
206
|
+
) -> np.ndarray:
|
|
207
|
+
"""
|
|
208
|
+
Calculate the extinction distribution by external mixing model.
|
|
209
|
+
|
|
210
|
+
Parameters
|
|
211
|
+
----------
|
|
212
|
+
dist : pd.Series
|
|
213
|
+
Particle size distribution data.
|
|
214
|
+
dp : float | Sequence[float]
|
|
215
|
+
Diameter(s) of the particles, either a single value or a sequence.
|
|
216
|
+
wavelength : float, optional
|
|
217
|
+
Wavelength of the incident light, default is 550 nm.
|
|
218
|
+
result_type : {'extinction', 'scattering', 'absorption'}, optional
|
|
219
|
+
Type of result to calculate, defaults to 'extinction'.
|
|
220
|
+
|
|
221
|
+
Returns
|
|
222
|
+
-------
|
|
223
|
+
np.ndarray
|
|
224
|
+
Extinction distribution calculated based on the external mixing model.
|
|
225
|
+
"""
|
|
226
|
+
refractive_dic = {'AS_volume_ratio': complex(1.53, 0.00),
|
|
227
|
+
'AN_volume_ratio': complex(1.55, 0.00),
|
|
228
|
+
'OM_volume_ratio': complex(1.54, 0.00),
|
|
229
|
+
'Soil_volume_ratio': complex(1.56, 0.01),
|
|
230
|
+
'SS_volume_ratio': complex(1.54, 0.00),
|
|
231
|
+
'EC_volume_ratio': complex(1.80, 0.54),
|
|
232
|
+
'ALWC_volume_ratio': complex(1.33, 0.00)}
|
|
233
|
+
|
|
234
|
+
ndp = np.array(dist[:np.size(dp)])
|
|
235
|
+
mie_results = (
|
|
236
|
+
Mie_PESD(refractive_dic[_specie], wavelength, dp, dist[_specie] / (1 + dist['ALWC_volume_ratio']) * ndp) for
|
|
237
|
+
_specie in refractive_dic)
|
|
238
|
+
|
|
239
|
+
ext_dist, sca_dist, abs_dist = (np.sum([res[0] for res in mie_results], axis=0),
|
|
240
|
+
np.sum([res[1] for res in mie_results], axis=0),
|
|
241
|
+
np.sum([res[2] for res in mie_results], axis=0))
|
|
242
|
+
|
|
243
|
+
if result_type == 'extinction':
|
|
244
|
+
return ext_dist
|
|
245
|
+
elif result_type == 'scattering':
|
|
246
|
+
return sca_dist
|
|
247
|
+
else:
|
|
248
|
+
return abs_dist
|
|
247
249
|
|
|
248
250
|
|
|
249
251
|
def core_shell():
|
|
250
|
-
|
|
252
|
+
pass
|
|
251
253
|
|
|
252
254
|
|
|
253
255
|
def sensitivity():
|
|
254
|
-
|
|
256
|
+
pass
|
|
255
257
|
|
|
256
258
|
|
|
257
259
|
if __name__ == '__main__':
|
|
258
|
-
|
|
260
|
+
result = Mie_Q(m=complex(1.5, 0.02), wavelength=550, dp=[100., 200.])
|
AeroViz/process/method/prop.py
CHANGED
|
@@ -4,59 +4,59 @@ from scipy.signal import find_peaks
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def geometric(dp: np.ndarray,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
dist: np.ndarray
|
|
8
|
+
) -> tuple[float, float]:
|
|
9
|
+
""" Calculate the geometric mean and standard deviation. """
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
_gmd = (((dist * log(dp)).sum()) / dist.sum())
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
logdp_mesh, gmd_mesh = np.meshgrid(log(dp), _gmd)
|
|
14
|
+
_gsd = ((((logdp_mesh - gmd_mesh) ** 2) * dist).sum() / dist.sum()) ** .5
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
return exp(_gmd), exp(_gsd)
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def contribution(dp: np.ndarray,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
dist: np.ndarray
|
|
21
|
+
) -> tuple[float, float, float]:
|
|
22
|
+
""" Calculate the relative contribution of each mode. """
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
ultra = dist[(dp >= 11.8) & (dp < 100)].sum() / dist.sum()
|
|
25
|
+
accum = dist[(dp >= 100) & (dp < 1000)].sum() / dist.sum()
|
|
26
|
+
coars = dist[(dp >= 1000) & (dp < 2500)].sum() / dist.sum()
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
return ultra, accum, coars
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def mode(dp: np.ndarray,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
dist: np.ndarray
|
|
33
|
+
) -> np.ndarray:
|
|
34
|
+
""" Find three peak mode in distribution. """
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
min_value = np.array([dist.min()])
|
|
37
|
+
mode, _ = find_peaks(np.concatenate([min_value, dist, min_value]), distance=len(dist) - 1)
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
return dp[mode - 1]
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def properties(dist,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
43
|
+
dp: np.ndarray,
|
|
44
|
+
dlogdp: np.ndarray,
|
|
45
|
+
weighting: str
|
|
46
|
+
) -> dict:
|
|
47
|
+
""" for apply """
|
|
48
|
+
dist = np.array(dist)
|
|
49
|
+
|
|
50
|
+
gmd, gsd = geometric(dp, dist)
|
|
51
|
+
ultra, accum, coarse = contribution(dp, dist)
|
|
52
|
+
peak = mode(dp, dist)
|
|
53
|
+
|
|
54
|
+
return {key: round(value, 3) for key, value in
|
|
55
|
+
{f'total_{weighting}': (dist * dlogdp).sum(),
|
|
56
|
+
f'GMD_{weighting}': gmd,
|
|
57
|
+
f'GSD_{weighting}': gsd,
|
|
58
|
+
f'mode_{weighting}': peak[0],
|
|
59
|
+
f'ultra_{weighting}': ultra,
|
|
60
|
+
f'accum_{weighting}': accum,
|
|
61
|
+
f'coarse_{weighting}': coarse}
|
|
62
|
+
.items()}
|