AeroViz 0.1.21__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.
- AeroViz/__init__.py +13 -0
- AeroViz/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/data/DEFAULT_DATA.csv +1417 -0
- AeroViz/data/DEFAULT_PNSD_DATA.csv +1417 -0
- AeroViz/data/hysplit_example_data.txt +101 -0
- AeroViz/dataProcess/Chemistry/__init__.py +149 -0
- AeroViz/dataProcess/Chemistry/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/dataProcess/Chemistry/_calculate.py +557 -0
- AeroViz/dataProcess/Chemistry/_isoropia.py +150 -0
- AeroViz/dataProcess/Chemistry/_mass_volume.py +487 -0
- AeroViz/dataProcess/Chemistry/_ocec.py +172 -0
- AeroViz/dataProcess/Chemistry/isrpia.cnf +21 -0
- AeroViz/dataProcess/Chemistry/isrpia2.exe +0 -0
- AeroViz/dataProcess/Optical/PyMieScatt_update.py +577 -0
- AeroViz/dataProcess/Optical/_IMPROVE.py +452 -0
- AeroViz/dataProcess/Optical/__init__.py +281 -0
- AeroViz/dataProcess/Optical/__pycache__/PyMieScatt_update.cpython-312.pyc +0 -0
- AeroViz/dataProcess/Optical/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/dataProcess/Optical/__pycache__/mie_theory.cpython-312.pyc +0 -0
- AeroViz/dataProcess/Optical/_derived.py +518 -0
- AeroViz/dataProcess/Optical/_extinction.py +123 -0
- AeroViz/dataProcess/Optical/_mie_sd.py +912 -0
- AeroViz/dataProcess/Optical/_retrieve_RI.py +243 -0
- AeroViz/dataProcess/Optical/coefficient.py +72 -0
- AeroViz/dataProcess/Optical/fRH.pkl +0 -0
- AeroViz/dataProcess/Optical/mie_theory.py +260 -0
- AeroViz/dataProcess/README.md +271 -0
- AeroViz/dataProcess/SizeDistr/__init__.py +245 -0
- AeroViz/dataProcess/SizeDistr/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/dataProcess/SizeDistr/__pycache__/_size_dist.cpython-312.pyc +0 -0
- AeroViz/dataProcess/SizeDistr/_size_dist.py +810 -0
- AeroViz/dataProcess/SizeDistr/merge/README.md +93 -0
- AeroViz/dataProcess/SizeDistr/merge/__init__.py +20 -0
- AeroViz/dataProcess/SizeDistr/merge/_merge_v0.py +251 -0
- AeroViz/dataProcess/SizeDistr/merge/_merge_v0_1.py +246 -0
- AeroViz/dataProcess/SizeDistr/merge/_merge_v1.py +255 -0
- AeroViz/dataProcess/SizeDistr/merge/_merge_v2.py +244 -0
- AeroViz/dataProcess/SizeDistr/merge/_merge_v3.py +518 -0
- AeroViz/dataProcess/SizeDistr/merge/_merge_v4.py +422 -0
- AeroViz/dataProcess/SizeDistr/prop.py +62 -0
- AeroViz/dataProcess/VOC/__init__.py +14 -0
- AeroViz/dataProcess/VOC/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/dataProcess/VOC/_potential_par.py +108 -0
- AeroViz/dataProcess/VOC/support_voc.json +446 -0
- AeroViz/dataProcess/__init__.py +66 -0
- AeroViz/dataProcess/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/dataProcess/core/__init__.py +272 -0
- AeroViz/dataProcess/core/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/mcp_server.py +352 -0
- AeroViz/plot/__init__.py +13 -0
- AeroViz/plot/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/plot/__pycache__/bar.cpython-312.pyc +0 -0
- AeroViz/plot/__pycache__/box.cpython-312.pyc +0 -0
- AeroViz/plot/__pycache__/pie.cpython-312.pyc +0 -0
- AeroViz/plot/__pycache__/radar.cpython-312.pyc +0 -0
- AeroViz/plot/__pycache__/regression.cpython-312.pyc +0 -0
- AeroViz/plot/__pycache__/scatter.cpython-312.pyc +0 -0
- AeroViz/plot/__pycache__/violin.cpython-312.pyc +0 -0
- AeroViz/plot/bar.py +126 -0
- AeroViz/plot/box.py +69 -0
- AeroViz/plot/distribution/__init__.py +1 -0
- AeroViz/plot/distribution/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/plot/distribution/__pycache__/distribution.cpython-312.pyc +0 -0
- AeroViz/plot/distribution/distribution.py +576 -0
- AeroViz/plot/meteorology/CBPF.py +295 -0
- AeroViz/plot/meteorology/__init__.py +3 -0
- AeroViz/plot/meteorology/__pycache__/CBPF.cpython-312.pyc +0 -0
- AeroViz/plot/meteorology/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/plot/meteorology/__pycache__/hysplit.cpython-312.pyc +0 -0
- AeroViz/plot/meteorology/__pycache__/wind_rose.cpython-312.pyc +0 -0
- AeroViz/plot/meteorology/hysplit.py +93 -0
- AeroViz/plot/meteorology/wind_rose.py +77 -0
- AeroViz/plot/optical/__init__.py +1 -0
- AeroViz/plot/optical/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/plot/optical/__pycache__/optical.cpython-312.pyc +0 -0
- AeroViz/plot/optical/optical.py +388 -0
- AeroViz/plot/pie.py +210 -0
- AeroViz/plot/radar.py +184 -0
- AeroViz/plot/regression.py +200 -0
- AeroViz/plot/scatter.py +174 -0
- AeroViz/plot/templates/__init__.py +6 -0
- AeroViz/plot/templates/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/plot/templates/__pycache__/ammonium_rich.cpython-312.pyc +0 -0
- AeroViz/plot/templates/__pycache__/contour.cpython-312.pyc +0 -0
- AeroViz/plot/templates/__pycache__/corr_matrix.cpython-312.pyc +0 -0
- AeroViz/plot/templates/__pycache__/diurnal_pattern.cpython-312.pyc +0 -0
- AeroViz/plot/templates/__pycache__/koschmieder.cpython-312.pyc +0 -0
- AeroViz/plot/templates/__pycache__/metal_heatmap.cpython-312.pyc +0 -0
- AeroViz/plot/templates/ammonium_rich.py +34 -0
- AeroViz/plot/templates/contour.py +47 -0
- AeroViz/plot/templates/corr_matrix.py +267 -0
- AeroViz/plot/templates/diurnal_pattern.py +61 -0
- AeroViz/plot/templates/koschmieder.py +95 -0
- AeroViz/plot/templates/metal_heatmap.py +164 -0
- AeroViz/plot/timeseries/__init__.py +2 -0
- AeroViz/plot/timeseries/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/plot/timeseries/__pycache__/template.cpython-312.pyc +0 -0
- AeroViz/plot/timeseries/__pycache__/timeseries.cpython-312.pyc +0 -0
- AeroViz/plot/timeseries/template.py +47 -0
- AeroViz/plot/timeseries/timeseries.py +446 -0
- AeroViz/plot/utils/__init__.py +4 -0
- AeroViz/plot/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/plot/utils/__pycache__/_color.cpython-312.pyc +0 -0
- AeroViz/plot/utils/__pycache__/_unit.cpython-312.pyc +0 -0
- AeroViz/plot/utils/__pycache__/plt_utils.cpython-312.pyc +0 -0
- AeroViz/plot/utils/__pycache__/sklearn_utils.cpython-312.pyc +0 -0
- AeroViz/plot/utils/_color.py +71 -0
- AeroViz/plot/utils/_unit.py +55 -0
- 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 +89 -0
- AeroViz/plot/violin.py +80 -0
- AeroViz/rawDataReader/FLOW.md +138 -0
- AeroViz/rawDataReader/__init__.py +220 -0
- AeroViz/rawDataReader/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/config/__init__.py +0 -0
- AeroViz/rawDataReader/config/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/config/__pycache__/supported_instruments.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/config/supported_instruments.py +135 -0
- AeroViz/rawDataReader/core/__init__.py +658 -0
- AeroViz/rawDataReader/core/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/core/__pycache__/logger.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/core/__pycache__/pre_process.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/core/__pycache__/qc.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/core/__pycache__/report.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/core/logger.py +171 -0
- AeroViz/rawDataReader/core/pre_process.py +308 -0
- AeroViz/rawDataReader/core/qc.py +961 -0
- AeroViz/rawDataReader/core/report.py +579 -0
- AeroViz/rawDataReader/script/AE33.py +173 -0
- AeroViz/rawDataReader/script/AE43.py +151 -0
- AeroViz/rawDataReader/script/APS.py +339 -0
- AeroViz/rawDataReader/script/Aurora.py +191 -0
- AeroViz/rawDataReader/script/BAM1020.py +90 -0
- AeroViz/rawDataReader/script/BC1054.py +161 -0
- AeroViz/rawDataReader/script/EPA.py +79 -0
- AeroViz/rawDataReader/script/GRIMM.py +68 -0
- AeroViz/rawDataReader/script/IGAC.py +140 -0
- AeroViz/rawDataReader/script/MA350.py +179 -0
- AeroViz/rawDataReader/script/Minion.py +218 -0
- AeroViz/rawDataReader/script/NEPH.py +199 -0
- AeroViz/rawDataReader/script/OCEC.py +173 -0
- AeroViz/rawDataReader/script/Q-ACSM.py +12 -0
- AeroViz/rawDataReader/script/SMPS.py +389 -0
- AeroViz/rawDataReader/script/TEOM.py +181 -0
- AeroViz/rawDataReader/script/VOC.py +106 -0
- AeroViz/rawDataReader/script/Xact.py +244 -0
- AeroViz/rawDataReader/script/__init__.py +28 -0
- AeroViz/rawDataReader/script/__pycache__/AE33.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/AE43.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/APS.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/Aurora.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/BAM1020.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/BC1054.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/EPA.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/GRIMM.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/IGAC.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/MA350.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/Minion.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/NEPH.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/OCEC.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/Q-ACSM.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/SMPS.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/TEOM.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/VOC.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/Xact.cpython-312.pyc +0 -0
- AeroViz/rawDataReader/script/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/tools/__init__.py +2 -0
- AeroViz/tools/__pycache__/__init__.cpython-312.pyc +0 -0
- AeroViz/tools/__pycache__/database.cpython-312.pyc +0 -0
- AeroViz/tools/__pycache__/dataclassifier.cpython-312.pyc +0 -0
- AeroViz/tools/database.py +95 -0
- AeroViz/tools/dataclassifier.py +117 -0
- AeroViz/tools/dataprinter.py +58 -0
- aeroviz-0.1.21.dist-info/METADATA +294 -0
- aeroviz-0.1.21.dist-info/RECORD +180 -0
- aeroviz-0.1.21.dist-info/WHEEL +5 -0
- aeroviz-0.1.21.dist-info/licenses/LICENSE +21 -0
- aeroviz-0.1.21.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
from ..core import Writer, run_process, deprecated
|
|
2
|
+
|
|
3
|
+
__all__ = ['Optical']
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Optical(Writer):
|
|
7
|
+
|
|
8
|
+
@run_process('Optical - scaCoe', 'scaCoe')
|
|
9
|
+
@deprecated(
|
|
10
|
+
"This method is now automatically called during file reading. Please update your code to use the pre-calculated values.")
|
|
11
|
+
def scaCoe(self, df_sca, instru, specified_band):
|
|
12
|
+
from .coefficient import _scaCoe
|
|
13
|
+
|
|
14
|
+
out = _scaCoe(df_sca, instru=instru, specified_band=[550] if specified_band is None else specified_band)
|
|
15
|
+
|
|
16
|
+
return self, out
|
|
17
|
+
|
|
18
|
+
@run_process('Optical - absCoe', 'absCoe')
|
|
19
|
+
@deprecated(
|
|
20
|
+
"This method is now automatically called during file reading. Please update your code to use the pre-calculated values.")
|
|
21
|
+
def absCoe(self, df_ae33, instru, specified_band):
|
|
22
|
+
from .coefficient import _absCoe
|
|
23
|
+
|
|
24
|
+
out = _absCoe(df_ae33, instru=instru, specified_band=[550] if specified_band is None else specified_band)
|
|
25
|
+
|
|
26
|
+
return self, out
|
|
27
|
+
|
|
28
|
+
@run_process('Optical - basic', 'opt_basic')
|
|
29
|
+
def basic(self, df_sca, df_abs, df_mass=None, df_no2=None, df_temp=None):
|
|
30
|
+
from ._extinction import _basic
|
|
31
|
+
|
|
32
|
+
out = _basic(df_sca, df_abs, df_mass, df_no2, df_temp)
|
|
33
|
+
|
|
34
|
+
return self, out
|
|
35
|
+
|
|
36
|
+
@run_process('Optical - Mie', 'Mie')
|
|
37
|
+
def Mie(self, df_psd, df_m, wavelength=550, psd_type='auto'):
|
|
38
|
+
"""
|
|
39
|
+
Calculate optical properties from PSD using Mie theory.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
df_psd : DataFrame
|
|
44
|
+
Particle number size distribution.
|
|
45
|
+
Columns are particle diameters (nm), rows are time points.
|
|
46
|
+
df_m : DataFrame or Series
|
|
47
|
+
Complex refractive index (n + ik) for each time point.
|
|
48
|
+
wavelength : float, default=550
|
|
49
|
+
Wavelength of incident light in nm.
|
|
50
|
+
psd_type : str, default='auto'
|
|
51
|
+
Type of PSD input:
|
|
52
|
+
- 'dNdlogDp': Number concentration per log bin width (#/cm³)
|
|
53
|
+
- 'dN': Number concentration per bin (#/cm³/bin)
|
|
54
|
+
- 'auto': Auto-detect with warning if uncertain
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
DataFrame
|
|
59
|
+
Optical coefficients with columns: ext, sca, abs (Mm⁻¹)
|
|
60
|
+
"""
|
|
61
|
+
from ._mie_sd import Mie_SD
|
|
62
|
+
|
|
63
|
+
# Get valid indices (where both PSD and RI have data)
|
|
64
|
+
original_index = df_psd.index.copy()
|
|
65
|
+
valid_index = df_psd.loc[df_m.dropna().index].dropna(how='all').index
|
|
66
|
+
|
|
67
|
+
# Calculate Mie for valid data only
|
|
68
|
+
psd_valid = df_psd.loc[valid_index]
|
|
69
|
+
ri_valid = df_m.loc[valid_index]
|
|
70
|
+
|
|
71
|
+
result = Mie_SD(ri_valid.values, wavelength, psd_valid, psd_type=psd_type)
|
|
72
|
+
|
|
73
|
+
# Reindex to original index (NaN for missing)
|
|
74
|
+
out = result.reindex(original_index)
|
|
75
|
+
|
|
76
|
+
return self, out
|
|
77
|
+
|
|
78
|
+
@run_process('Optical - IMPROVE', 'IMPROVE')
|
|
79
|
+
def IMPROVE(self, df_mass, df_RH=None, method='revised', df_nh4_status=None):
|
|
80
|
+
"""
|
|
81
|
+
Calculate extinction using IMPROVE equation.
|
|
82
|
+
|
|
83
|
+
Parameters
|
|
84
|
+
----------
|
|
85
|
+
df_mass : DataFrame
|
|
86
|
+
Mass concentrations with columns: AS, AN, OM, Soil, SS, EC
|
|
87
|
+
df_RH : DataFrame, optional
|
|
88
|
+
Relative humidity data
|
|
89
|
+
method : str, default='revised'
|
|
90
|
+
IMPROVE version: 'revised' or 'modified'
|
|
91
|
+
df_nh4_status : DataFrame, optional
|
|
92
|
+
NH4 status from reconstruction_basic()['NH4_status'].
|
|
93
|
+
If provided, rows with 'Deficiency' status will be excluded.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
dict
|
|
98
|
+
Dictionary with keys:
|
|
99
|
+
- 'dry': Dry extinction DataFrame
|
|
100
|
+
- 'wet': Wet extinction DataFrame (if df_RH provided)
|
|
101
|
+
- 'ALWC': Water contribution (wet - dry)
|
|
102
|
+
- 'fRH': Hygroscopic growth factor
|
|
103
|
+
"""
|
|
104
|
+
from ._IMPROVE import revised, modified
|
|
105
|
+
|
|
106
|
+
if method == 'revised':
|
|
107
|
+
out = revised(df_mass, df_RH, df_nh4_status)
|
|
108
|
+
elif method == 'modified':
|
|
109
|
+
out = modified(df_mass, df_RH, df_nh4_status)
|
|
110
|
+
else:
|
|
111
|
+
raise ValueError(f"method must be 'revised' or 'modified', got '{method}'")
|
|
112
|
+
|
|
113
|
+
return self, out
|
|
114
|
+
|
|
115
|
+
@run_process('Optical - gas_extinction', 'gas_ext')
|
|
116
|
+
def gas_extinction(self, df_no2, df_temp):
|
|
117
|
+
"""
|
|
118
|
+
Calculate gas contribution to extinction.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
df_no2 : DataFrame
|
|
123
|
+
NO2 concentration (ppb)
|
|
124
|
+
df_temp : DataFrame
|
|
125
|
+
Ambient temperature (Celsius)
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
DataFrame
|
|
130
|
+
Gas extinction with ScatteringByGas, AbsorptionByGas, ExtinctionByGas
|
|
131
|
+
"""
|
|
132
|
+
from ._IMPROVE import gas_extinction as calc_gas_ext
|
|
133
|
+
|
|
134
|
+
out = calc_gas_ext(df_no2, df_temp)
|
|
135
|
+
|
|
136
|
+
return self, out
|
|
137
|
+
|
|
138
|
+
@run_process('Optical - retrieve_RI', 'retrieve_RI')
|
|
139
|
+
def retrieve_RI(self, df_optical, df_pnsd, dlogdp=0.014, wavelength=550):
|
|
140
|
+
"""
|
|
141
|
+
Retrieve refractive index from optical and PSD measurements.
|
|
142
|
+
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
df_optical : DataFrame
|
|
146
|
+
Optical data with Extinction, Scattering, Absorption columns
|
|
147
|
+
df_pnsd : DataFrame
|
|
148
|
+
Particle number size distribution data
|
|
149
|
+
dlogdp : float, default=0.014
|
|
150
|
+
Logarithmic bin width
|
|
151
|
+
wavelength : float, default=550
|
|
152
|
+
Wavelength in nm
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
DataFrame
|
|
157
|
+
Retrieved refractive index with re_real and re_imaginary columns
|
|
158
|
+
"""
|
|
159
|
+
from ._retrieve_RI import retrieve_RI
|
|
160
|
+
|
|
161
|
+
out = retrieve_RI(df_optical, df_pnsd, dlogdp, wavelength)
|
|
162
|
+
|
|
163
|
+
return self, out
|
|
164
|
+
|
|
165
|
+
@run_process('Optical - derived', 'derived')
|
|
166
|
+
def derived(self, df_sca=None, df_abs=None, df_ext=None, df_no2=None, df_o3=None,
|
|
167
|
+
df_ec=None, df_oc=None, df_pm1=None, df_pm25=None, df_improve=None):
|
|
168
|
+
"""
|
|
169
|
+
Calculate derived optical and atmospheric parameters.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
df_sca : DataFrame, optional
|
|
174
|
+
Scattering coefficient (Mm-1)
|
|
175
|
+
df_abs : DataFrame, optional
|
|
176
|
+
Absorption coefficient (Mm-1)
|
|
177
|
+
df_ext : DataFrame, optional
|
|
178
|
+
Extinction coefficient (Mm-1)
|
|
179
|
+
df_no2 : DataFrame, optional
|
|
180
|
+
NO2 concentration (ppb)
|
|
181
|
+
df_o3 : DataFrame, optional
|
|
182
|
+
O3 concentration (ppb)
|
|
183
|
+
df_ec : DataFrame, optional
|
|
184
|
+
Elemental carbon (ug/m3)
|
|
185
|
+
df_oc : DataFrame, optional
|
|
186
|
+
Organic carbon (ug/m3)
|
|
187
|
+
df_pm1 : DataFrame, optional
|
|
188
|
+
PM1 (ug/m3)
|
|
189
|
+
df_pm25 : DataFrame, optional
|
|
190
|
+
PM2.5 (ug/m3)
|
|
191
|
+
df_improve : DataFrame, optional
|
|
192
|
+
IMPROVE extinction data
|
|
193
|
+
|
|
194
|
+
Returns
|
|
195
|
+
-------
|
|
196
|
+
DataFrame
|
|
197
|
+
Derived parameters (PG, MAC, Ox, Vis_cal, fRH_IMPR, OCEC_ratio, etc.)
|
|
198
|
+
"""
|
|
199
|
+
from ._derived import derived_parameters
|
|
200
|
+
|
|
201
|
+
out = derived_parameters(
|
|
202
|
+
df_sca=df_sca, df_abs=df_abs, df_ext=df_ext,
|
|
203
|
+
df_no2=df_no2, df_o3=df_o3, df_ec=df_ec, df_oc=df_oc,
|
|
204
|
+
df_pm1=df_pm1, df_pm25=df_pm25, df_improve=df_improve
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
return self, out
|
|
208
|
+
|
|
209
|
+
@run_process('Optical - BrC', 'BrC')
|
|
210
|
+
def BrC(self, df_abs, wavelengths=None, ref_wavelength=880, aae_bc=1.0):
|
|
211
|
+
"""
|
|
212
|
+
Calculate Brown Carbon (BrC) absorption by separating BC and BrC contributions.
|
|
213
|
+
|
|
214
|
+
This method uses the AAE-based separation approach:
|
|
215
|
+
1. Assume Black Carbon (BC) has AAE = 1.0 (or user-specified value)
|
|
216
|
+
2. Absorption at 880nm is entirely from BC (reference wavelength)
|
|
217
|
+
3. Calculate BC absorption at shorter wavelengths using power law
|
|
218
|
+
4. BrC absorption = Total absorption - BC absorption
|
|
219
|
+
5. Calculate BrC AAE from the derived spectrum
|
|
220
|
+
|
|
221
|
+
Parameters
|
|
222
|
+
----------
|
|
223
|
+
df_abs : DataFrame
|
|
224
|
+
Absorption coefficient data with columns like 'abs_370', 'abs_470',
|
|
225
|
+
'abs_520', 'abs_590', 'abs_660', 'abs_880'.
|
|
226
|
+
Units should be Mm-1.
|
|
227
|
+
wavelengths : list[int], optional
|
|
228
|
+
Wavelengths to calculate BrC absorption for.
|
|
229
|
+
Default: [370, 470, 520, 590, 660]
|
|
230
|
+
ref_wavelength : int, default=880
|
|
231
|
+
Reference wavelength (nm) assumed to be purely BC absorption.
|
|
232
|
+
aae_bc : float, default=1.0
|
|
233
|
+
Absorption Ångström Exponent for Black Carbon.
|
|
234
|
+
Typical range: 0.8-1.1 for fresh BC.
|
|
235
|
+
|
|
236
|
+
Returns
|
|
237
|
+
-------
|
|
238
|
+
DataFrame
|
|
239
|
+
- abs_BC_{wl}: BC absorption at each wavelength (Mm-1)
|
|
240
|
+
- abs_BrC_{wl}: BrC absorption at each wavelength (Mm-1, NaN if invalid)
|
|
241
|
+
- BrC_fraction_{wl}: BrC contribution fraction (0-1, NaN if invalid)
|
|
242
|
+
- AAE_BrC: BrC Absorption Ångström Exponent (NaN if invalid)
|
|
243
|
+
|
|
244
|
+
Examples
|
|
245
|
+
--------
|
|
246
|
+
>>> from AeroViz import RawDataReader, DataProcess
|
|
247
|
+
>>> # Read AE33 data (has multi-wavelength absorption)
|
|
248
|
+
>>> ae33 = RawDataReader(instrument='AE33', path='/data/AE33',
|
|
249
|
+
... start='2024-01-01', end='2024-01-31')
|
|
250
|
+
>>> # Calculate BrC
|
|
251
|
+
>>> optical = DataProcess(method='Optical')
|
|
252
|
+
>>> brc_result = optical.BrC(ae33)
|
|
253
|
+
>>> # Check valid data (non-NaN)
|
|
254
|
+
>>> valid_brc = brc_result['AAE_BrC'].dropna()
|
|
255
|
+
>>> print(valid_brc.mean())
|
|
256
|
+
|
|
257
|
+
Notes
|
|
258
|
+
-----
|
|
259
|
+
The separation assumes AAE_BC ≈ 1.0 based on Mie theory for graphitic
|
|
260
|
+
carbon. Real BC may have slightly different AAE depending on mixing
|
|
261
|
+
state and size distribution.
|
|
262
|
+
|
|
263
|
+
**Validity check**: If calculated BC absorption exceeds total absorption
|
|
264
|
+
at ANY wavelength, the entire row is marked as invalid (NaN for all
|
|
265
|
+
BrC-related values). This indicates the AAE=1 assumption is not valid.
|
|
266
|
+
|
|
267
|
+
References
|
|
268
|
+
----------
|
|
269
|
+
- Lack & Langridge (2013), ACP 13:8321-8341
|
|
270
|
+
- Kirchstetter et al. (2004), JGR 109:D21208
|
|
271
|
+
"""
|
|
272
|
+
from ._derived import calculate_BrC_absorption
|
|
273
|
+
|
|
274
|
+
out = calculate_BrC_absorption(
|
|
275
|
+
df_abs=df_abs,
|
|
276
|
+
wavelengths=wavelengths,
|
|
277
|
+
ref_wavelength=ref_wavelength,
|
|
278
|
+
aae_bc=aae_bc
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
return self, out
|
|
Binary file
|
|
Binary file
|