AeroViz 0.1.2__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/config/DEFAULT_DATA.csv +1417 -0
- AeroViz/config/DEFAULT_PNSD_DATA.csv +1417 -0
- 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/VOC/voc_par.json +464 -0
- 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/fRH.json +390 -0
- AeroViz/plot/utils/plt_utils.py +92 -0
- AeroViz/plot/utils/sklearn_utils.py +49 -0
- AeroViz/plot/utils/units.json +84 -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.2.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.2.dist-info/RECORD +0 -106
- {AeroViz-0.1.2.dist-info → AeroViz-0.1.3b0.dist-info}/LICENSE +0 -0
- {AeroViz-0.1.2.dist-info → AeroViz-0.1.3b0.dist-info}/WHEEL +0 -0
- {AeroViz-0.1.2.dist-info → AeroViz-0.1.3b0.dist-info}/top_level.txt +0 -0
AeroViz/plot/optical/optical.py
CHANGED
|
@@ -10,246 +10,246 @@ from AeroViz.plot.utils import *
|
|
|
10
10
|
from AeroViz.process.method.mie_theory import Mie_Q, Mie_MEE, Mie_PESD
|
|
11
11
|
|
|
12
12
|
__all__ = ['Q_plot',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
'RI_couple',
|
|
14
|
+
'RRI_2D',
|
|
15
|
+
# 'scattering_phase',
|
|
16
|
+
'response_surface',
|
|
17
|
+
]
|
|
18
18
|
|
|
19
19
|
mapping_dic = {'AS': {'m': 1.53 + 0j, 'density': 1.73, 'label': fr'$NH_{4}NO_{3}$', 'color': '#A65E58'},
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
'AN': {'m': 1.55 + 0j, 'density': 1.77, 'label': fr'$(NH_{4})_{2}SO_{4}$', 'color': '#A5BF6B'},
|
|
21
|
+
'OM': {'m': 1.54 + 0j, 'density': 1.40, 'label': 'OM', 'color': '#F2BF5E'},
|
|
22
|
+
'Soil': {'m': 1.56 + 0.01j, 'density': 2.60, 'label': 'Soil', 'color': '#3F83BF'},
|
|
23
|
+
'SS': {'m': 1.54 + 0j, 'density': 1.90, 'label': 'SS', 'color': '#B777C2'},
|
|
24
|
+
'BC': {'m': 1.80 + 0.54j, 'density': 1.50, 'label': 'BC', 'color': '#D1CFCB'},
|
|
25
|
+
'Water': {'m': 1.333 + 0j, 'density': 1.00, 'label': 'Water', 'color': '#96c8e6'}}
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
@set_figure
|
|
29
29
|
def Q_plot(species: Literal["AS", "AN", "OM", "Soil", "SS", "BC", "Water"] | list[
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
Literal["AS", "AN", "OM", "Soil", "SS", "BC", "Water"]],
|
|
31
|
+
x: Literal["dp", "sp"] = 'dp',
|
|
32
|
+
y: Literal["Q", "MEE"] = "Q",
|
|
33
|
+
mode: Literal["ext", "sca", "abs"] = 'ext',
|
|
34
|
+
**kwargs) -> tuple[Figure, Axes]:
|
|
35
|
+
"""
|
|
36
|
+
Generate a plot showing optical efficiency or mass optical efficiency for different particle species.
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
species : Union[Literal["AS", "AN", "OM", "Soil", "SS", "BC", "Water"], list[Literal["AS", "AN", "OM", "Soil", "SS", "BC", "Water"]]]
|
|
41
|
+
The particle species or list of particle species to plot. Valid species include 'AS' (Ammonium Sulfate),
|
|
42
|
+
'AN' (Ammonium Nitrate), 'OM' (Organic Matter), 'Soil', 'SS' (Sea Salt), 'BC' (Black Carbon), and 'Water'.
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
x : Literal["dp", "sp"], optional
|
|
45
|
+
The x-axis parameter. 'dp' represents particle diameter, and 'sp' represents size parameter (alpha).
|
|
46
|
+
Default is 'dp'.
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
y : Literal["Q", "MEE"], optional
|
|
49
|
+
The y-axis parameter. 'Q' represents optical efficiency (Q_ext, Q_sca, Q_abs), and 'MEE' represents
|
|
50
|
+
mass optical efficiency (MEE, MSE, MAE). Default is 'Q'.
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
mode : Literal["ext", "sca", "abs"], optional
|
|
53
|
+
The mode of efficiency to plot. 'ext' for extinction efficiency, 'sca' for scattering efficiency,
|
|
54
|
+
and 'abs' for absorption efficiency. Default is 'ext'.
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
**kwargs
|
|
57
|
+
Additional keyword arguments to pass to the plot function.
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
ax : Axes
|
|
62
|
+
Matplotlib Axes object containing the generated plot.
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
Examples
|
|
65
|
+
--------
|
|
66
|
+
Example usage of the Q_plot function:
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
>>> Q_plot('AS', x='dp', y='Q', mode='ext')
|
|
69
|
+
>>> Q_plot(['AS', 'AN'], x='sp', y='MEE')
|
|
70
|
+
"""
|
|
71
|
+
dp = np.geomspace(10, 10000, 2000)
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
mode_mapping = {'ext': 0, 'sca': 1, 'abs': 2}
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
xlabel_mapping = {'dp': 'Particle Diameter (nm)',
|
|
76
|
+
'sp': 'Size parameter (\\alpha)'}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
ylabel_mapping = {'Q': {'ext': r'$Extinction\ efficiency\ (Q_{ext})$',
|
|
79
|
+
'sca': r'$Scattering\ efficiency\ (Q_{sca})$',
|
|
80
|
+
'abs': r'$Absorption\ efficiency\ (Q_{abs})$'},
|
|
81
|
+
'MEE': {'ext': r'$MEE\ (m^{2}/g)$',
|
|
82
|
+
'sca': r'$MSE\ (m^{2}/g)$',
|
|
83
|
+
'abs': r'$MAE\ (m^{2}/g)$'}}
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
typ = mode_mapping.get(mode, None)
|
|
86
|
+
xlabel = xlabel_mapping.get(x, None)
|
|
87
|
+
ylabel = ylabel_mapping.get(y, None).get(mode, None)
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
fig, ax = plt.subplots()
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
if x == "sp":
|
|
92
|
+
size_para = math.pi * dp.copy() / 550
|
|
93
|
+
dp_ = size_para
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
else:
|
|
96
|
+
plt.semilogx()
|
|
97
|
+
dp_ = dp.copy()
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
if isinstance(species, list):
|
|
100
|
+
for i, specie in enumerate(species):
|
|
101
|
+
label = mapping_dic[specie].get('label', None)
|
|
102
|
+
color = mapping_dic[specie].get('color', None)
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
mapping_dic[specie]['Q'] = Mie_Q(mapping_dic[specie]['m'], 550, dp)
|
|
105
|
+
mapping_dic[specie]['MEE'] = Mie_MEE(mapping_dic[specie]['m'], 550, dp, mapping_dic[specie]['density'])
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
plt.plot(dp_, mapping_dic[specie][f'{y}'][typ], color=color, label=label, alpha=1, lw=2)
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
else:
|
|
110
|
+
legend_label = {'Q': [r'$\bf Q_{{ext}}$', r'$\bf Q_{{scat}}$', r'$\bf Q_{{abs}}$'],
|
|
111
|
+
'MEE': [r'$\bf MEE$', r'$\bf MSE$', r'$\bf MAE$']}
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
ylabel_mapping = {'Q': r'$\bf Optical\ efficiency\ (Q_{{ext, sca, abs}})$',
|
|
114
|
+
'MEE': r'$\bf Mass\ Optical\ Efficiency\ (m^2/g)$'}
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
legend = legend_label.get(y, None)
|
|
117
|
+
ylabel = ylabel_mapping.get(y, None)
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
mapping_dic[species]['Q'] = Mie_Q(mapping_dic[species]['m'], 550, dp)
|
|
120
|
+
mapping_dic[species]['MEE'] = Mie_MEE(mapping_dic[species]['m'], 550, dp, mapping_dic[species]['density'])
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
plt.plot(dp_, mapping_dic[species][f'{y}'][0], color='b', label=legend[0])
|
|
123
|
+
plt.plot(dp_, mapping_dic[species][f'{y}'][1], color='g', label=legend[1])
|
|
124
|
+
plt.plot(dp_, mapping_dic[species][f'{y}'][2], color='r', label=legend[2])
|
|
125
|
+
plt.text(0.04, 0.92, mapping_dic[species]['label'], transform=ax.transAxes, weight='bold')
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
ax.set(xlim=(dp.min(), dp.max()), ylim=(0, None), xlabel=xlabel, ylabel=ylabel)
|
|
128
|
+
ax.grid(color='k', axis='x', which='major', linestyle='dashdot', linewidth=0.4, alpha=0.4)
|
|
129
|
+
ax.legend(loc='best', prop={'weight': 'bold'})
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
# fig.savefig(PATH_MAIN/f'Q_{species}')
|
|
132
|
+
plt.show()
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
return fig, ax
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
@set_figure(figsize=(9, 4))
|
|
138
138
|
def RI_couple(**kwargs) -> tuple[Figure, Axes]:
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
"""
|
|
140
|
+
Generate a plot to test the influence of imaginary parts on scattering and absorption efficiencies.
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
**kwargs
|
|
145
|
+
Additional keyword arguments to pass to the plot function.
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
ax : Axes
|
|
150
|
+
Matplotlib Axes object containing the generated plot.
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
Examples
|
|
153
|
+
--------
|
|
154
|
+
Example usage of the IJ_couple function:
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
>>> ax = RI_couple()
|
|
157
|
+
"""
|
|
158
|
+
dp = np.geomspace(10, 10000, 5000)
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
a = Mie_Q(1.50 + 0.01j, 550, dp)
|
|
161
|
+
b = Mie_Q(1.50 + 0.1j, 550, dp)
|
|
162
|
+
c = Mie_Q(1.50 + 0.5j, 550, dp)
|
|
163
163
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
fig, ax = plt.subplots(1, 2)
|
|
165
|
+
plt.subplots_adjust(right=0.9, wspace=0.4)
|
|
166
|
+
(ax1, ax2) = ax
|
|
167
|
+
size_para = math.pi * dp / 550
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
ax1.plot(size_para, a[1], 'k-', alpha=1, label=r'$\bf\ k\ =\ 0.01$')
|
|
170
|
+
ax1.plot(size_para, b[1], 'b-', alpha=1, label=r'$\bf\ k\ =\ 0.10$')
|
|
171
|
+
ax1.plot(size_para, c[1], 'g-', alpha=1, label=r'$\bf\ k\ =\ 0.50$')
|
|
172
|
+
ax1.legend()
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
174
|
+
ax1.set_xlim(0, size_para[-1])
|
|
175
|
+
ax1.set_ylim(0, None)
|
|
176
|
+
ax1.set_xlabel(r'$\bf Size\ parameter\ (\alpha)$')
|
|
177
|
+
ax1.set_ylabel(r'$\bf Scattering\ efficiency\ (Q_{{scat}})$')
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
ax2.plot(size_para, a[2], 'k-', alpha=1, label=r'$\bf\ k\ =\ 0.01$')
|
|
180
|
+
ax2.plot(size_para, b[2], 'b-', alpha=1, label=r'$\bf\ k\ =\ 0.10$')
|
|
181
|
+
ax2.plot(size_para, c[2], 'g-', alpha=1, label=r'$\bf\ k\ =\ 0.50$')
|
|
182
|
+
ax2.legend()
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
ax2.set_xlim(0, size_para[-1])
|
|
185
|
+
ax2.set_ylim(0, None)
|
|
186
|
+
ax2.set_xlabel(r'$\bf Size\ parameter\ (\alpha)$')
|
|
187
|
+
ax2.set_ylabel(r'$\bf Absorption\ efficiency\ (Q_{{abs}})$')
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
fig.suptitle(r'$\bf n\ =\ 1.50 $')
|
|
190
|
+
# fig.savefig(PATH_MAIN/f'IJ_couple')
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
plt.show()
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
return fig, ax
|
|
195
195
|
|
|
196
196
|
|
|
197
197
|
@set_figure
|
|
198
198
|
def RRI_2D(mode: Literal["ext", "sca", "abs"] = 'ext',
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
**kwargs) -> tuple[Figure, Axes]:
|
|
200
|
+
"""
|
|
201
|
+
Generate a 2D plot of scattering efficiency (Q) against real and imaginary parts of the refractive index.
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
Parameters
|
|
204
|
+
----------
|
|
205
|
+
mode : {'ext', 'sca', 'abs'}, optional
|
|
206
|
+
The mode of scattering efficiency to plot:
|
|
207
|
+
- 'ext' for extinction efficiency (Q_ext)
|
|
208
|
+
- 'sca' for scattering efficiency (Q_sca)
|
|
209
|
+
- 'abs' for absorption efficiency (Q_abs)
|
|
210
|
+
Default is 'ext'.
|
|
211
211
|
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
**kwargs
|
|
213
|
+
Additional keyword arguments to pass to the plot function.
|
|
214
214
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
Returns
|
|
216
|
+
-------
|
|
217
|
+
ax : Axes
|
|
218
|
+
Matplotlib Axes object containing the generated 2D plot.
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
Examples
|
|
221
|
+
--------
|
|
222
|
+
Example usage of the RRI_2D function:
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
>>> RRI_2D(mode='sca', xlabel='Real Part (n)', ylabel='Imaginary Part (k)', title='Scattering Efficiency 2D Plot')
|
|
225
|
+
"""
|
|
226
|
+
mode_mapping = {'ext': 0, 'sca': 1, 'abs': 2}
|
|
227
227
|
|
|
228
|
-
|
|
228
|
+
typ = mode_mapping.get(mode, None)
|
|
229
229
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
for dp in [400, 550, 700]:
|
|
231
|
+
RRI = np.linspace(1.3, 2, 100)
|
|
232
|
+
IRI = np.linspace(0, 0.7, 100)
|
|
233
|
+
arr = np.zeros((RRI.size, IRI.size))
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
235
|
+
for i, I_RI in enumerate(IRI):
|
|
236
|
+
for j, R_RI in enumerate(RRI):
|
|
237
|
+
arr[i, j] = Mie_Q(R_RI + 1j * I_RI, 550, dp)[typ]
|
|
238
238
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
fig, ax = plt.subplots()
|
|
240
|
+
plt.title(fr'$\bf dp\ = {dp}\ nm$', )
|
|
241
|
+
plt.xlabel(r'$\bf Real\ part\ (n)$', )
|
|
242
|
+
plt.ylabel(r'$\bf Imaginary\ part\ (k)$', )
|
|
243
243
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
244
|
+
im = plt.imshow(arr, extent=(1.3, 2, 0, 0.7), cmap='jet', origin='lower')
|
|
245
|
+
color_bar = plt.colorbar(im, extend='both')
|
|
246
|
+
color_bar.set_label(label=fr'$\bf Q_{{{mode}}}$')
|
|
247
247
|
|
|
248
|
-
|
|
248
|
+
# fig.savefig(PATH_MAIN/f'RRI_{mode}_{dp}')
|
|
249
249
|
|
|
250
|
-
|
|
250
|
+
plt.show()
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
return fig, ax
|
|
253
253
|
|
|
254
254
|
|
|
255
255
|
# @set_figure
|
|
@@ -305,84 +305,84 @@ def RRI_2D(mode: Literal["ext", "sca", "abs"] = 'ext',
|
|
|
305
305
|
#
|
|
306
306
|
# plt.show()
|
|
307
307
|
# return fig, ax
|
|
308
|
-
|
|
308
|
+
|
|
309
309
|
|
|
310
310
|
@set_figure
|
|
311
311
|
def response_surface(real_range=(1.33, 1.7),
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
312
|
+
gmd_range=(10, 500),
|
|
313
|
+
num=50,
|
|
314
|
+
**kwargs) -> tuple[Figure, Axes]:
|
|
315
|
+
"""
|
|
316
|
+
Generate a response surface plot for sensitivity tests of extinction based on Mie scattering.
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
318
|
+
Parameters
|
|
319
|
+
----------
|
|
320
|
+
real_range : tuple, optional
|
|
321
|
+
The range of real part (refractive index) values for sensitivity testing. Default is (1.33, 1.7).
|
|
322
322
|
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
gmd_range : tuple, optional
|
|
324
|
+
The range of geometric mean diameter (GMD) values for sensitivity testing. Default is (60, 400).
|
|
325
325
|
|
|
326
|
-
|
|
327
|
-
|
|
326
|
+
num : int, optional
|
|
327
|
+
The number of points to generate within the specified ranges. Default is 50.
|
|
328
328
|
|
|
329
|
-
|
|
330
|
-
|
|
329
|
+
**kwargs
|
|
330
|
+
Additional keyword arguments to pass to the plot function.
|
|
331
331
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
332
|
+
Returns
|
|
333
|
+
-------
|
|
334
|
+
ax : Axes
|
|
335
|
+
Matplotlib Axes object containing the generated response surface plot.
|
|
336
336
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
337
|
+
Examples
|
|
338
|
+
--------
|
|
339
|
+
Example usage of the response_surface function:
|
|
340
340
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
341
|
+
>>> response_surface(real_range=(1.4, 1.6), gmd_range=(100, 300), num=30, xlabel='Real Part (n)',
|
|
342
|
+
... ylabel='GMD (nm)', zlabel='Extinction (1/Mm)', title='Sensitivity Tests of Extinction')
|
|
343
|
+
"""
|
|
344
344
|
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
def function(RI, GMD):
|
|
346
|
+
Z = np.zeros_like(RI) # 使用 np.zeros_like 可以確保 Z 和 RI 具有相同的形狀
|
|
347
347
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
348
|
+
for i in range(RI.shape[0]):
|
|
349
|
+
for j in range(RI.shape[1]):
|
|
350
|
+
_RI, _GMD = RI[i, j], GMD[i, j]
|
|
351
|
+
Bext, Bsca, Babs = Mie_PESD(m=_RI, lognormal=True, geoMean=_GMD, geoStdDev=2.)
|
|
352
|
+
Z[i, j] = np.sum(Bext)
|
|
353
353
|
|
|
354
|
-
|
|
354
|
+
return Z
|
|
355
355
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
356
|
+
# 假設 RI、GSD、GMD
|
|
357
|
+
RI = np.linspace(real_range[0], real_range[1], num)
|
|
358
|
+
GMD = np.linspace(gmd_range[0], gmd_range[1], num)
|
|
359
359
|
|
|
360
|
-
|
|
361
|
-
|
|
360
|
+
# 建立三維 meshgrid
|
|
361
|
+
real, gmd = np.meshgrid(RI, GMD, indexing='xy')
|
|
362
362
|
|
|
363
|
-
|
|
364
|
-
|
|
363
|
+
# Result
|
|
364
|
+
ext = function(real, gmd)
|
|
365
365
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
366
|
+
# plot
|
|
367
|
+
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
|
|
368
|
+
ax.plot_surface(real, gmd, ext, rstride=1, cstride=1, cmap=plt.get_cmap('jet'), edgecolor='none')
|
|
369
369
|
|
|
370
|
-
|
|
371
|
-
|
|
370
|
+
ax.set(xlabel='Real part (n)', ylabel='GMD (nm)', zlabel=Unit('Extinction'),
|
|
371
|
+
title='Sensitive tests of Extinction')
|
|
372
372
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
373
|
+
ax.zaxis.get_offset_text().set_visible(False)
|
|
374
|
+
exponent = math.floor(math.log10(np.max(ext)))
|
|
375
|
+
ax.text(ax.get_xlim()[1] * 1.01, ax.get_ylim()[1], ax.get_zlim()[1] * 1.1, s=fr'${{\times}}\ 10^{exponent}$')
|
|
376
|
+
ax.ticklabel_format(style='sci', axis='z', scilimits=(0, 0), useOffset=False)
|
|
377
377
|
|
|
378
|
-
|
|
378
|
+
plt.show()
|
|
379
379
|
|
|
380
|
-
|
|
380
|
+
return fig, ax
|
|
381
381
|
|
|
382
382
|
|
|
383
383
|
if __name__ == '__main__':
|
|
384
|
-
|
|
385
|
-
|
|
384
|
+
Q_plot(['AS', 'AN', 'OM', 'Soil', 'SS', 'BC'], x='dp', y='MEE')
|
|
385
|
+
Q_plot(['AS', 'AN', 'OM', 'Soil', 'SS', 'BC'], x='dp', y='Q')
|
|
386
386
|
|
|
387
|
-
|
|
388
|
-
|
|
387
|
+
# RI_couple()
|
|
388
|
+
# response_surface()
|