AeroViz 0.1.3__py3-none-any.whl → 0.1.4__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.

Files changed (121) hide show
  1. AeroViz/__init__.py +7 -5
  2. AeroViz/{config → data}/DEFAULT_DATA.csv +1 -1
  3. AeroViz/dataProcess/Chemistry/__init__.py +40 -40
  4. AeroViz/dataProcess/Chemistry/_calculate.py +15 -15
  5. AeroViz/dataProcess/Chemistry/_isoropia.py +72 -68
  6. AeroViz/dataProcess/Chemistry/_mass_volume.py +158 -161
  7. AeroViz/dataProcess/Chemistry/_ocec.py +109 -109
  8. AeroViz/dataProcess/Chemistry/_partition.py +19 -18
  9. AeroViz/dataProcess/Chemistry/_teom.py +9 -11
  10. AeroViz/dataProcess/Chemistry/isrpia.cnf +21 -0
  11. AeroViz/dataProcess/Optical/Angstrom_exponent.py +20 -0
  12. AeroViz/dataProcess/Optical/_IMPROVE.py +40 -41
  13. AeroViz/dataProcess/Optical/__init__.py +29 -44
  14. AeroViz/dataProcess/Optical/_absorption.py +21 -47
  15. AeroViz/dataProcess/Optical/_extinction.py +31 -25
  16. AeroViz/dataProcess/Optical/_mie.py +5 -7
  17. AeroViz/dataProcess/Optical/_mie_sd.py +89 -90
  18. AeroViz/dataProcess/Optical/_scattering.py +19 -20
  19. AeroViz/dataProcess/SizeDistr/__init__.py +39 -39
  20. AeroViz/dataProcess/SizeDistr/__merge.py +159 -158
  21. AeroViz/dataProcess/SizeDistr/_merge.py +155 -154
  22. AeroViz/dataProcess/SizeDistr/_merge_v1.py +162 -161
  23. AeroViz/dataProcess/SizeDistr/_merge_v2.py +153 -152
  24. AeroViz/dataProcess/SizeDistr/_merge_v3.py +327 -327
  25. AeroViz/dataProcess/SizeDistr/_merge_v4.py +273 -275
  26. AeroViz/dataProcess/SizeDistr/_size_distr.py +51 -51
  27. AeroViz/dataProcess/VOC/__init__.py +9 -9
  28. AeroViz/dataProcess/VOC/_potential_par.py +53 -55
  29. AeroViz/dataProcess/__init__.py +28 -6
  30. AeroViz/dataProcess/core/__init__.py +59 -65
  31. AeroViz/plot/__init__.py +7 -2
  32. AeroViz/plot/bar.py +126 -0
  33. AeroViz/plot/box.py +69 -0
  34. AeroViz/plot/distribution/distribution.py +421 -427
  35. AeroViz/plot/meteorology/meteorology.py +240 -292
  36. AeroViz/plot/optical/__init__.py +0 -1
  37. AeroViz/plot/optical/optical.py +230 -230
  38. AeroViz/plot/pie.py +198 -0
  39. AeroViz/plot/regression.py +196 -0
  40. AeroViz/plot/scatter.py +165 -0
  41. AeroViz/plot/templates/__init__.py +2 -4
  42. AeroViz/plot/templates/ammonium_rich.py +34 -0
  43. AeroViz/plot/templates/contour.py +25 -25
  44. AeroViz/plot/templates/corr_matrix.py +86 -93
  45. AeroViz/plot/templates/diurnal_pattern.py +28 -26
  46. AeroViz/plot/templates/koschmieder.py +59 -123
  47. AeroViz/plot/templates/metal_heatmap.py +135 -37
  48. AeroViz/plot/timeseries/__init__.py +1 -0
  49. AeroViz/plot/timeseries/template.py +47 -0
  50. AeroViz/plot/timeseries/timeseries.py +324 -264
  51. AeroViz/plot/utils/__init__.py +2 -1
  52. AeroViz/plot/utils/_color.py +57 -57
  53. AeroViz/plot/utils/_unit.py +48 -48
  54. AeroViz/plot/utils/plt_utils.py +92 -0
  55. AeroViz/plot/utils/sklearn_utils.py +49 -0
  56. AeroViz/plot/utils/units.json +5 -0
  57. AeroViz/plot/violin.py +80 -0
  58. AeroViz/process/__init__.py +17 -17
  59. AeroViz/process/core/DataProc.py +9 -9
  60. AeroViz/process/core/SizeDist.py +81 -81
  61. AeroViz/process/method/PyMieScatt_update.py +488 -488
  62. AeroViz/process/method/mie_theory.py +231 -229
  63. AeroViz/process/method/prop.py +40 -40
  64. AeroViz/process/script/AbstractDistCalc.py +103 -103
  65. AeroViz/process/script/Chemical.py +168 -167
  66. AeroViz/process/script/IMPACT.py +40 -40
  67. AeroViz/process/script/IMPROVE.py +152 -152
  68. AeroViz/process/script/Others.py +45 -45
  69. AeroViz/process/script/PSD.py +26 -26
  70. AeroViz/process/script/PSD_dry.py +69 -70
  71. AeroViz/process/script/retrieve_RI.py +50 -51
  72. AeroViz/rawDataReader/__init__.py +53 -58
  73. AeroViz/rawDataReader/config/supported_instruments.py +155 -0
  74. AeroViz/rawDataReader/core/__init__.py +233 -356
  75. AeroViz/rawDataReader/script/AE33.py +17 -18
  76. AeroViz/rawDataReader/script/AE43.py +18 -21
  77. AeroViz/rawDataReader/script/APS_3321.py +30 -30
  78. AeroViz/rawDataReader/script/Aurora.py +23 -24
  79. AeroViz/rawDataReader/script/BC1054.py +36 -40
  80. AeroViz/rawDataReader/script/EPA_vertical.py +37 -9
  81. AeroViz/rawDataReader/script/GRIMM.py +16 -23
  82. AeroViz/rawDataReader/script/IGAC.py +90 -0
  83. AeroViz/rawDataReader/script/MA350.py +32 -39
  84. AeroViz/rawDataReader/script/Minion.py +103 -0
  85. AeroViz/rawDataReader/script/NEPH.py +69 -74
  86. AeroViz/rawDataReader/script/SMPS_TH.py +25 -25
  87. AeroViz/rawDataReader/script/SMPS_aim11.py +32 -32
  88. AeroViz/rawDataReader/script/SMPS_genr.py +31 -31
  89. AeroViz/rawDataReader/script/Sunset_OCEC.py +60 -0
  90. AeroViz/rawDataReader/script/TEOM.py +30 -28
  91. AeroViz/rawDataReader/script/Table.py +13 -14
  92. AeroViz/rawDataReader/script/VOC.py +26 -0
  93. AeroViz/rawDataReader/script/__init__.py +18 -20
  94. AeroViz/tools/database.py +64 -66
  95. AeroViz/tools/dataclassifier.py +106 -106
  96. AeroViz/tools/dataprinter.py +51 -51
  97. AeroViz/tools/datareader.py +38 -38
  98. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/METADATA +5 -4
  99. AeroViz-0.1.4.dist-info/RECORD +112 -0
  100. AeroViz/plot/improve/__init__.py +0 -1
  101. AeroViz/plot/improve/improve.py +0 -240
  102. AeroViz/plot/optical/aethalometer.py +0 -77
  103. AeroViz/plot/templates/event_evolution.py +0 -65
  104. AeroViz/plot/templates/regression.py +0 -256
  105. AeroViz/plot/templates/scatter.py +0 -130
  106. AeroViz/plot/templates/templates.py +0 -398
  107. AeroViz/plot/utils/_decorator.py +0 -74
  108. AeroViz/rawDataReader/script/IGAC_TH.py +0 -104
  109. AeroViz/rawDataReader/script/IGAC_ZM.py +0 -90
  110. AeroViz/rawDataReader/script/OCEC_LCRES.py +0 -34
  111. AeroViz/rawDataReader/script/OCEC_RES.py +0 -28
  112. AeroViz/rawDataReader/script/VOC_TH.py +0 -30
  113. AeroViz/rawDataReader/script/VOC_ZM.py +0 -37
  114. AeroViz/rawDataReader/utils/__init__.py +0 -0
  115. AeroViz/rawDataReader/utils/config.py +0 -169
  116. AeroViz-0.1.3.dist-info/RECORD +0 -111
  117. /AeroViz/{config → data}/DEFAULT_PNSD_DATA.csv +0 -0
  118. /AeroViz/{config → rawDataReader/config}/__init__.py +0 -0
  119. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/LICENSE +0 -0
  120. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/WHEEL +0 -0
  121. {AeroViz-0.1.3.dist-info → AeroViz-0.1.4.dist-info}/top_level.txt +0 -0
@@ -1,175 +1,172 @@
1
- from pandas import date_range, concat, DataFrame, to_numeric
1
+ from pandas import concat, DataFrame
2
2
 
3
3
 
4
4
  def _basic(df_che, df_ref, df_water, df_density, nam_lst):
5
- df_all = concat(df_che, axis=1)
6
- index = df_all.index.copy()
7
- df_all.columns = nam_lst
8
-
9
- ## parameter
10
- mol_A, mol_S, mol_N = df_all['NH4+'] / 18, df_all['SO42-'] / 96, df_all['NO3-'] / 62
11
- df_all['status'] = (mol_A) / (2 * mol_S + mol_N)
12
-
13
- convert_nam = {'AS': 'SO42-',
14
- 'AN': 'NO3-',
15
- 'OM': 'OC',
16
- 'Soil': 'Fe',
17
- 'SS': 'Na+',
18
- 'EC': 'EC',
19
- }
20
-
21
- mass_coe = {'AS': 1.375,
22
- 'AN': 1.29,
23
- 'OM': 1.8,
24
- 'Soil': 28.57,
25
- 'SS': 2.54,
26
- 'EC': 1,
27
- }
28
-
29
- vol_coe = {'AS': 1.76,
30
- 'AN': 1.73,
31
- 'OM': 1.4,
32
- 'Soil': 2.6,
33
- 'SS': 2.16,
34
- 'EC': 1.5,
35
- }
36
-
37
- RI_coe = {'550': {'ALWC': 1.333 + 0j,
38
- 'AS': 1.53 + 0j,
39
- 'AN': 1.55 + 0j,
40
- 'OM': 1.55 + 0.0163j,
41
- 'Soil': 1.56 + 0.006j,
42
- 'SS': 1.54 + 0j,
43
- 'EC': 1.80 + 0.72j,
44
- },
45
-
46
- ## m + kj -> m value is same as 550 current
47
- '450': {'ALWC': 1.333 + 0j,
48
- 'AS': 1.57 + 0j,
49
- 'AN': 1.57 + 0j,
50
- 'OM': 1.58 + 0.056,
51
- 'Soil': 1.56 + 0.009j,
52
- 'SS': 1.54 + 0j,
53
- 'EC': 1.80 + 0.79j,
54
- },
55
- }
56
-
57
- ## mass
58
- ## NH4 Enough
59
- df_mass = DataFrame()
60
- df_enough = df_all.where(df_all['status'] >= 1).dropna().copy()
61
-
62
- for _mass_nam, _coe in mass_coe.items():
63
- df_mass[_mass_nam] = df_all[convert_nam[_mass_nam]] * _coe
64
-
65
- ## NH4 Deficiency
66
- defic_idx = df_all['status'] < 1
67
-
68
- if defic_idx.any():
69
- residual = mol_A - 2 * mol_S
70
-
71
- ## residual > 0
72
- _status = residual > 0
73
- if _status.any():
74
- _cond = _status & (residual <= mol_N)
75
- df_mass.loc[_cond, 'AN'] = residual.loc[_cond] * 80
76
-
77
- _cond = _status & (residual > mol_N)
78
- df_mass.loc[_cond, 'AN'] = mol_N.loc[_cond] * 80
79
-
80
- ## residual < 0
81
- _status = residual <= 0
82
- if _status.any():
83
- df_mass.loc[_status, 'AN'] = 0
84
-
85
- _cond = _status & (mol_A <= 2 * mol_S)
86
- df_mass.loc[_cond, 'AS'] = mol_A.loc[_cond] / 2 * 132
87
-
88
- _cond = _status & (mol_A > 2 * mol_S)
89
- df_mass.loc[_cond, 'AS'] = mol_S.loc[_cond] * 132
90
-
91
- df_mass_cal = df_mass.dropna().copy()
92
- df_mass['total'] = df_mass.sum(axis=1, min_count=6)
93
-
94
- qc_ratio = df_mass['total'] / df_ref
95
- qc_cond = (qc_ratio >= 0.7) & (qc_ratio <= 1.3)
96
-
97
- ## volume
98
- df_vol = DataFrame()
99
- for _vol_nam, _coe in vol_coe.items():
100
- df_vol[_vol_nam] = df_mass_cal[_vol_nam] / _coe
101
-
102
- if df_water is not None:
103
- df_vol['ALWC'] = df_water
104
- df_vol = df_vol.dropna()
105
- df_vol['total_wet'] = df_vol.sum(axis=1, min_count=6)
106
-
107
- df_vol['total_dry'] = df_vol[vol_coe.keys()].sum(axis=1, min_count=6)
108
-
109
- ## density
110
- df_vol_cal = DataFrame()
111
- df_den_rec = df_mass['total'] / df_vol['total_dry']
112
- if df_density is not None:
113
- df_den_all = concat([df_all[['SO42-', 'NO3-', 'NH4+', 'EC']], df_density, df_mass['OM']], axis=1).dropna()
114
-
115
- df_vol_cal = (df_den_all[['SO42-', 'NO3-', 'NH4+']].sum(axis=1) / 1.75) + \
116
- df_den_all['Cl-'] / 1.52 + \
117
- df_den_all['OM'] / 1.4 + df_den_all['EC'] / 1.77
118
-
119
- df_den = df_den_all.sum(axis=1, min_count=6) / df_vol_cal
120
- # df_den = df_den_all.sum(axis=1) / df_vol_cal
121
- # df_den = df_mass['total'].loc[df_den_all.index] / df_vol_cal
122
-
123
- ## refractive index
124
- ri_dic = {}
125
- for _lambda, _coe in RI_coe.items():
5
+ df_all = concat(df_che, axis=1)
6
+ index = df_all.index.copy()
7
+ df_all.columns = nam_lst
8
+
9
+ # parameter
10
+ mol_A, mol_S, mol_N = df_all['NH4+'] / 18, df_all['SO42-'] / 96, df_all['NO3-'] / 62
11
+ df_all['status'] = (mol_A) / (2 * mol_S + mol_N)
12
+
13
+ convert_nam = {'AS': 'SO42-',
14
+ 'AN': 'NO3-',
15
+ 'OM': 'OC',
16
+ 'Soil': 'Fe',
17
+ 'SS': 'Na+',
18
+ 'EC': 'EC',
19
+ }
20
+
21
+ mass_coe = {'AS': 1.375,
22
+ 'AN': 1.29,
23
+ 'OM': 1.8,
24
+ 'Soil': 28.57,
25
+ 'SS': 2.54,
26
+ 'EC': 1,
27
+ }
28
+
29
+ vol_coe = {'AS': 1.76,
30
+ 'AN': 1.73,
31
+ 'OM': 1.4,
32
+ 'Soil': 2.6,
33
+ 'SS': 2.16,
34
+ 'EC': 1.5,
35
+ }
36
+
37
+ RI_coe = {'550': {'ALWC': 1.333 + 0j,
38
+ 'AS': 1.53 + 0j,
39
+ 'AN': 1.55 + 0j,
40
+ 'OM': 1.55 + 0.0163j,
41
+ 'Soil': 1.56 + 0.006j,
42
+ 'SS': 1.54 + 0j,
43
+ 'EC': 1.80 + 0.72j,
44
+ },
45
+
46
+ # m + kj -> m value is same as 550 current
47
+ '450': {'ALWC': 1.333 + 0j,
48
+ 'AS': 1.57 + 0j,
49
+ 'AN': 1.57 + 0j,
50
+ 'OM': 1.58 + 0.056,
51
+ 'Soil': 1.56 + 0.009j,
52
+ 'SS': 1.54 + 0j,
53
+ 'EC': 1.80 + 0.79j,
54
+ },
55
+ }
56
+
57
+ # mass
58
+ # NH4 Enough
59
+ df_mass = DataFrame()
60
+ df_enough = df_all.where(df_all['status'] >= 1).dropna().copy()
61
+
62
+ for _mass_nam, _coe in mass_coe.items():
63
+ df_mass[_mass_nam] = df_all[convert_nam[_mass_nam]] * _coe
64
+
65
+ # NH4 Deficiency
66
+ defic_idx = df_all['status'] < 1
67
+
68
+ if defic_idx.any():
69
+ residual = mol_A - 2 * mol_S
70
+
71
+ # residual > 0
72
+ _status = residual > 0
73
+ if _status.any():
74
+ _cond = _status & (residual <= mol_N)
75
+ df_mass.loc[_cond, 'AN'] = residual.loc[_cond] * 80
76
+
77
+ _cond = _status & (residual > mol_N)
78
+ df_mass.loc[_cond, 'AN'] = mol_N.loc[_cond] * 80
79
+
80
+ # residual < 0
81
+ _status = residual <= 0
82
+ if _status.any():
83
+ df_mass.loc[_status, 'AN'] = 0
84
+
85
+ _cond = _status & (mol_A <= 2 * mol_S)
86
+ df_mass.loc[_cond, 'AS'] = mol_A.loc[_cond] / 2 * 132
87
+
88
+ _cond = _status & (mol_A > 2 * mol_S)
89
+ df_mass.loc[_cond, 'AS'] = mol_S.loc[_cond] * 132
90
+
91
+ df_mass_cal = df_mass.dropna().copy()
92
+ df_mass['total'] = df_mass.sum(axis=1, min_count=6)
93
+
94
+ qc_ratio = df_mass['total'] / df_ref
95
+ qc_cond = (qc_ratio >= 0.7) & (qc_ratio <= 1.3)
96
+
97
+ # volume
98
+ df_vol = DataFrame()
99
+ for _vol_nam, _coe in vol_coe.items():
100
+ df_vol[_vol_nam] = df_mass_cal[_vol_nam] / _coe
101
+
102
+ if df_water is not None:
103
+ df_vol['ALWC'] = df_water.copy()
104
+ df_vol = df_vol.dropna()
105
+ df_vol['total_wet'] = df_vol.sum(axis=1, min_count=6)
106
+
107
+ df_vol['total_dry'] = df_vol[vol_coe.keys()].sum(axis=1, min_count=6)
108
+
109
+ # density
110
+ df_vol_cal = DataFrame()
111
+ df_den_rec = df_mass['total'] / df_vol['total_dry']
112
+ if df_density is not None:
113
+ df_den_all = concat([df_all[['SO42-', 'NO3-', 'NH4+', 'EC']], df_density, df_mass['OM']], axis=1).dropna()
114
+
115
+ df_vol_cal = (df_den_all[['SO42-', 'NO3-', 'NH4+']].sum(axis=1) / 1.75) + \
116
+ df_den_all['Cl-'] / 1.52 + \
117
+ df_den_all['OM'] / 1.4 + df_den_all['EC'] / 1.77
118
+
119
+ df_den = df_den_all.sum(axis=1, min_count=6) / df_vol_cal
120
+ else:
121
+ df_den = df_den_rec
122
+
123
+ # refractive index
124
+ ri_dic = {}
125
+ for _lambda, _coe in RI_coe.items():
126
+
127
+ df_RI = DataFrame()
128
+
129
+ for _ky, _df in df_vol.items():
130
+ if 'total' in _ky: continue
131
+ df_RI[_ky] = (_df * _coe[_ky])
132
+
133
+ df_RI['RI_wet'] = None
134
+ if df_water is not None:
135
+ df_RI['RI_wet'] = (df_RI / df_vol['total_wet'].to_frame().values).sum(axis=1)
126
136
 
127
- df_RI = DataFrame()
137
+ df_RI['RI_dry'] = (df_RI[vol_coe.keys()] / df_vol['total_dry'].to_frame().values).sum(axis=1)
128
138
 
129
- for _ky, _df in df_vol.items():
130
- if 'total' in _ky: continue
131
- df_RI[_ky] = (_df * _coe[_ky])
139
+ ri_dic[f'RI_{_lambda}'] = df_RI[['RI_dry', 'RI_wet']]
132
140
 
133
- df_RI['RI_wet'] = None
134
- if df_water is not None:
135
- df_RI['RI_wet'] = (df_RI / df_vol['total_wet'].to_frame().values).sum(axis=1)
141
+ # mole and equivalent
142
+ df_eq = concat((mol_A, mol_S, mol_N, mol_A * 1, mol_S * 2, mol_N * 1), axis=1)
143
+ df_eq.columns = ['mol_NH4', 'mol_SO4', 'mol_NO3', 'eq_NH4', 'eq_SO4', 'eq_NO3', ]
136
144
 
137
- df_RI['RI_dry'] = (df_RI[vol_coe.keys()] / df_vol['total_dry'].to_frame().values).sum(axis=1)
145
+ # out
146
+ out = {'mass': df_mass,
147
+ 'volume': df_vol,
148
+ 'vol_cal': df_vol_cal,
149
+ 'eq': df_eq,
150
+ 'density_mat': df_den,
151
+ 'density_rec': df_den_rec,
152
+ }
153
+ out.update(ri_dic)
138
154
 
139
- ri_dic[f'RI_{_lambda}'] = df_RI[['RI_dry', 'RI_wet']]
155
+ for _ky, _df in out.items():
156
+ out[_ky] = _df.reindex(index).where(qc_cond)
140
157
 
141
- ## mole and equivalent
142
- df_eq = concat((mol_A, mol_S, mol_N, mol_A * 1, mol_S * 2, mol_N * 1), axis=1)
143
- df_eq.columns = ['mol_NH4', 'mol_SO4', 'mol_NO3', 'eq_NH4', 'eq_SO4', 'eq_NO3', ]
144
-
145
- ## out
146
- out = {'mass': df_mass,
147
- 'volume': df_vol,
148
- 'vol_cal': df_vol_cal,
149
- 'eq': df_eq,
150
- 'density_mat': df_den,
151
- 'density_rec': df_den_rec,
152
- }
153
- out.update(ri_dic)
154
-
155
- for _ky, _df in out.items():
156
- out[_ky] = _df.reindex(index).where(qc_cond)
157
-
158
- return out
159
-
160
-
161
- # '''
158
+ return out
162
159
 
163
160
 
164
161
  def mass_ratio(_df):
165
- if _df['PM25'] >= _df['total_mass']:
166
- _df['others'] = _df['PM25'] - _df['total_mass']
167
- for _val, _species in zip(_df.values, _df.index):
168
- _df[f'{_species}_ratio'] = _val / _df['PM25'].__round__(3)
162
+ if _df['PM25'] >= _df['total_mass']:
163
+ _df['others'] = _df['PM25'] - _df['total_mass']
164
+ for _val, _species in zip(_df.values, _df.index):
165
+ _df[f'{_species}_ratio'] = _val / _df['PM25'].__round__(3)
169
166
 
170
- if _df['PM25'] < _df['total_mass']:
171
- _df['others'] = 0
172
- for _val, _species in zip(_df.values, _df.index):
173
- _df[f'{_species}_ratio'] = _val / _df['PM25'].__round__(3)
167
+ if _df['PM25'] < _df['total_mass']:
168
+ _df['others'] = 0
169
+ for _val, _species in zip(_df.values, _df.index):
170
+ _df[f'{_species}_ratio'] = _val / _df['PM25'].__round__(3)
174
171
 
175
- return _df['others':].drop(labels=['PM25_ratio', 'total_mass_ratio'])
172
+ return _df['others':].drop(labels=['PM25_ratio', 'total_mass_ratio'])
@@ -1,161 +1,161 @@
1
- from AeroViz.dataProcess.core import _union_index
2
-
3
- from pandas import date_range, concat, DataFrame, to_numeric
4
- from scipy.optimize import curve_fit
5
1
  import numpy as np
2
+ from pandas import concat, DataFrame
3
+ from scipy.optimize import curve_fit
4
+
5
+ from AeroViz.dataProcess.core import union_index
6
6
 
7
7
  __all__ = [
8
- '_basic',
9
- # '_ocec_ratio_cal',
8
+ '_basic',
9
+ # '_ocec_ratio_cal',
10
10
  ]
11
11
 
12
12
 
13
13
  def _min_Rsq(_oc, _ec, _rng):
14
- _val_mesh, _oc_mesh = np.meshgrid(_rng, _oc)
15
- _val_mesh, _ec_mesh = np.meshgrid(_rng, _ec)
14
+ _val_mesh, _oc_mesh = np.meshgrid(_rng, _oc)
15
+ _val_mesh, _ec_mesh = np.meshgrid(_rng, _ec)
16
16
 
17
- _out_table = DataFrame(_oc_mesh - _val_mesh * _ec_mesh, index=_oc.index, columns=_rng)
17
+ _out_table = DataFrame(_oc_mesh - _val_mesh * _ec_mesh, index=_oc.index, columns=_rng)
18
18
 
19
- ## calculate R2
20
- _r2_dic = {}
21
- _func = lambda _x, _sl, _inte: _sl * _x + _inte
22
- for _ocec, _out in _out_table.items():
23
- _df = DataFrame([_out.values, _ec.values]).T.dropna()
19
+ ## calculate R2
20
+ _r2_dic = {}
21
+ _func = lambda _x, _sl, _inte: _sl * _x + _inte
22
+ for _ocec, _out in _out_table.items():
23
+ _df = DataFrame([_out.values, _ec.values]).T.dropna()
24
24
 
25
- _x, _y = _df[0], _df[1]
26
- _opt, _ = curve_fit(_func, _x, _y)
25
+ _x, _y = _df[0], _df[1]
26
+ _opt, _ = curve_fit(_func, _x, _y)
27
27
 
28
- _tss = np.sum((_y - _y.mean()) ** 2.)
29
- _rss = np.sum((_y - _func(_x, *_opt)) ** 2.)
28
+ _tss = np.sum((_y - _y.mean()) ** 2.)
29
+ _rss = np.sum((_y - _func(_x, *_opt)) ** 2.)
30
30
 
31
- _r2_dic[round(_ocec, 3)] = 1. - _rss / _tss
31
+ _r2_dic[round(_ocec, 3)] = 1. - _rss / _tss
32
32
 
33
- ## get the min R2
34
- _ratio = DataFrame(_r2_dic, index=[0]).idxmin(axis=1).values[0]
33
+ ## get the min R2
34
+ _ratio = DataFrame(_r2_dic, index=[0]).idxmin(axis=1).values[0]
35
35
 
36
- return _ratio, _out_table[_ratio]
36
+ return _ratio, _out_table[_ratio]
37
37
 
38
38
 
39
39
  def _ocec_ratio_cal(_nam, _lcres_splt, _hr_lim, _range_, _wisoc_range_):
40
- ## parameter
41
- _out = DataFrame(index=_lcres_splt.index)
42
- (_, _oc), (_, _ec) = _lcres_splt.items()
43
- # _oc, _ec = _lcres_splt['Thermal_OC'], _lcres_splt['Thermal_EC']
40
+ ## parameter
41
+ _out = DataFrame(index=_lcres_splt.index)
42
+ (_, _oc), (_, _ec) = _lcres_splt.items()
43
+ # _oc, _ec = _lcres_splt['Thermal_OC'], _lcres_splt['Thermal_EC']
44
44
 
45
- ## real data OC/EC
46
- _ocec_ratio_real = (_oc / _ec).quantile(.5)
45
+ ## real data OC/EC
46
+ _ocec_ratio_real = (_oc / _ec).quantile(.5)
47
47
 
48
- _out[f'OC/EC_real_{_nam}'] = _ocec_ratio_real
49
- _out[f'POC_real_{_nam}'] = _ocec_ratio_real * _ec
50
- _out[f'SOC_real_{_nam}'] = _oc - _out[f'POC_real_{_nam}']
48
+ _out[f'OC/EC_real_{_nam}'] = _ocec_ratio_real
49
+ _out[f'POC_real_{_nam}'] = _ocec_ratio_real * _ec
50
+ _out[f'SOC_real_{_nam}'] = _oc - _out[f'POC_real_{_nam}']
51
51
 
52
- ## the least R2 method
53
- ## estimated OC/EC
54
- if (len(_lcres_splt) <= _hr_lim):
55
- print(f"\t\t{_lcres_splt.index[0].strftime('%Y-%m-%d %X')} to {_lcres_splt.index[-1].strftime('%Y-%m-%d %X')}")
56
- print('\t\tPlease Modify the Values of "hour_limit" or Input Sufficient Amount of Data !!')
52
+ ## the least R2 method
53
+ ## estimated OC/EC
54
+ if (len(_lcres_splt) <= _hr_lim):
55
+ print(f"\t\t{_lcres_splt.index[0].strftime('%Y-%m-%d %X')} to {_lcres_splt.index[-1].strftime('%Y-%m-%d %X')}")
56
+ print('\t\tPlease Modify the Values of "hour_limit" or Input Sufficient Amount of Data !!')
57
57
 
58
- _out[[f'OC/EC_{_nam}', f'POC_{_nam}', f'SOC_{_nam}', f'WISOC/OC_{_nam}', f'WSOC_{_nam}',
59
- f'WISOC_{_nam}']] = np.nan
58
+ _out[[f'OC/EC_{_nam}', f'POC_{_nam}', f'SOC_{_nam}', f'WISOC/OC_{_nam}', f'WSOC_{_nam}',
59
+ f'WISOC_{_nam}']] = np.nan
60
60
 
61
- return _out
61
+ return _out
62
62
 
63
- if (len(_lcres_splt.dropna()) == 0):
64
- _out[[f'OC/EC_{_nam}', f'POC_{_nam}', f'SOC_{_nam}', f'WISOC/OC_{_nam}', f'WSOC_{_nam}',
65
- f'WISOC_{_nam}']] = np.nan
63
+ if (len(_lcres_splt.dropna()) == 0):
64
+ _out[[f'OC/EC_{_nam}', f'POC_{_nam}', f'SOC_{_nam}', f'WISOC/OC_{_nam}', f'WSOC_{_nam}',
65
+ f'WISOC_{_nam}']] = np.nan
66
66
 
67
- return _out
67
+ return _out
68
68
 
69
- ## OC/EC
70
- _ocec_ratio = False
71
- _st, _ed, _stp = _range_
69
+ ## OC/EC
70
+ _ocec_ratio = False
71
+ _st, _ed, _stp = _range_
72
72
 
73
- for _ in range(2):
74
- if _ocec_ratio:
75
- _ocec_rng = np.arange(_ocec_ratio - _stp / 2, _ocec_ratio + _stp / 2, .01).round(3)
76
- else:
77
- _ocec_rng = np.arange(_st, _ed + _stp, _stp).round(3)
73
+ for _ in range(2):
74
+ if _ocec_ratio:
75
+ _ocec_rng = np.arange(_ocec_ratio - _stp / 2, _ocec_ratio + _stp / 2, .01).round(3)
76
+ else:
77
+ _ocec_rng = np.arange(_st, _ed + _stp, _stp).round(3)
78
78
 
79
- _ocec_ratio, _soc = _min_Rsq(_oc, _ec, _ocec_rng)
79
+ _ocec_ratio, _soc = _min_Rsq(_oc, _ec, _ocec_rng)
80
80
 
81
- ## WISOC
82
- _st, _ed, _stp = _wisoc_range_
83
- _wisoc_rng = (np.arange(_st, _ed + _stp, _stp) * _ocec_ratio).round(5)
84
- _wisoc_ratio, _wsoc = _min_Rsq(_oc, _ec, _wisoc_rng)
81
+ ## WISOC
82
+ _st, _ed, _stp = _wisoc_range_
83
+ _wisoc_rng = (np.arange(_st, _ed + _stp, _stp) * _ocec_ratio).round(5)
84
+ _wisoc_ratio, _wsoc = _min_Rsq(_oc, _ec, _wisoc_rng)
85
85
 
86
- ## out
87
- _out[f'OC/EC_{_nam}'] = _ocec_ratio
88
- _out[f'SOC_{_nam}'] = _soc
89
- _out[f'POC_{_nam}'] = _oc - _out[f'SOC_{_nam}']
90
- _out[f'WISOC/OC_{_nam}'] = _wisoc_ratio
91
- _out[f'WSOC_{_nam}'] = _wsoc
92
- _out[f'WISOC_{_nam}'] = _oc - _out[f'WSOC_{_nam}']
86
+ ## out
87
+ _out[f'OC/EC_{_nam}'] = _ocec_ratio
88
+ _out[f'SOC_{_nam}'] = _soc
89
+ _out[f'POC_{_nam}'] = _oc - _out[f'SOC_{_nam}']
90
+ _out[f'WISOC/OC_{_nam}'] = _wisoc_ratio
91
+ _out[f'WSOC_{_nam}'] = _wsoc
92
+ _out[f'WISOC_{_nam}'] = _oc - _out[f'WSOC_{_nam}']
93
93
 
94
- return _out[[f'OC/EC_{_nam}', f'POC_{_nam}', f'SOC_{_nam}', f'WISOC/OC_{_nam}', f'WSOC_{_nam}', f'WISOC_{_nam}',
95
- f'OC/EC_real_{_nam}', f'POC_real_{_nam}', f'SOC_real_{_nam}']]
94
+ return _out[[f'OC/EC_{_nam}', f'POC_{_nam}', f'SOC_{_nam}', f'WISOC/OC_{_nam}', f'WSOC_{_nam}', f'WISOC_{_nam}',
95
+ f'OC/EC_real_{_nam}', f'POC_real_{_nam}', f'SOC_real_{_nam}']]
96
96
 
97
97
 
98
98
  def _basic(_lcres, _res, _mass, _ocec_ratio, _ocec_ratio_month, _hr_lim, _range, _wisoc_range):
99
- _lcres, _res, _mass = _union_index(_lcres, _res, _mass)
99
+ _lcres, _res, _mass = union_index(_lcres, _res, _mass)
100
100
 
101
- _out = {}
101
+ _out = {}
102
102
 
103
- ## OC1, OC2, OC3, OC4, PC
104
- _df_bsc = _res / _lcres['Sample_Volume'].to_frame().values.copy()
103
+ ## OC1, OC2, OC3, OC4, PC
104
+ _df_bsc = _res / _lcres['Sample_Volume'].to_frame().values.copy()
105
105
 
106
- ## SOC, POC, OC/EC
107
- if _ocec_ratio is not None:
108
- try:
109
- iter(_ocec_ratio)
110
- except TypeError:
111
- raise TypeError('"ocec_ratio" Only Accept a Single Value !!')
106
+ ## SOC, POC, OC/EC
107
+ if _ocec_ratio is not None:
108
+ try:
109
+ iter(_ocec_ratio)
110
+ except TypeError:
111
+ raise TypeError('"ocec_ratio" Only Accept a Single Value !!')
112
112
 
113
- _prcs_df = DataFrame(index=_df_bsc.index)
114
- _prcs_df['OC/EC'] = _ocec_ratio
115
- _prcs_df['POC'] = _ocec_ratio * _lcres['Thermal_EC']
116
- _prcs_df['SOC'] = _lcres['Thermal_OC'] - _prcs_df['POC']
113
+ _prcs_df = DataFrame(index=_df_bsc.index)
114
+ _prcs_df['OC/EC'] = _ocec_ratio
115
+ _prcs_df['POC'] = _ocec_ratio * _lcres['Thermal_EC']
116
+ _prcs_df['SOC'] = _lcres['Thermal_OC'] - _prcs_df['POC']
117
117
 
118
- else:
119
- _df_lst = []
120
- for _, _df in _lcres.resample(f'{_ocec_ratio_month}MS', closed='left'):
121
- _thm_cal = _ocec_ratio_cal('thm', _df[['Thermal_OC', 'Thermal_EC']], _hr_lim, _range, _wisoc_range)
122
- _opt_cal = _ocec_ratio_cal('opt', _df[['Optical_OC', 'Optical_EC']], _hr_lim, _range, _wisoc_range)
123
- _df_lst.append(concat([_thm_cal, _opt_cal], axis=1))
118
+ else:
119
+ _df_lst = []
120
+ for _, _df in _lcres.resample(f'{_ocec_ratio_month}MS', closed='left'):
121
+ _thm_cal = _ocec_ratio_cal('thm', _df[['Thermal_OC', 'Thermal_EC']], _hr_lim, _range, _wisoc_range)
122
+ _opt_cal = _ocec_ratio_cal('opt', _df[['Optical_OC', 'Optical_EC']], _hr_lim, _range, _wisoc_range)
123
+ _df_lst.append(concat([_thm_cal, _opt_cal], axis=1))
124
124
 
125
- _prcs_df = concat(_df_lst)
125
+ _prcs_df = concat(_df_lst)
126
126
 
127
- _df_bsc = concat((_df_bsc.copy(), _prcs_df), axis=1)
127
+ _df_bsc = concat((_df_bsc.copy(), _prcs_df), axis=1)
128
128
 
129
- ## ratio
130
- _df_ratio = DataFrame(index=_df_bsc.index)
129
+ ## ratio
130
+ _df_ratio = DataFrame(index=_df_bsc.index)
131
131
 
132
- for _ky, _val in _df_bsc.items():
133
- if 'OC/EC' in _ky: continue
134
- _df_ratio[f'{_ky}/Thermal_OC'] = _val / _lcres['Thermal_OC']
135
- _df_ratio[f'{_ky}/Optical_OC'] = _val / _lcres['Optical_OC']
132
+ for _ky, _val in _df_bsc.items():
133
+ if 'OC/EC' in _ky: continue
134
+ _df_ratio[f'{_ky}/Thermal_OC'] = _val / _lcres['Thermal_OC']
135
+ _df_ratio[f'{_ky}/Optical_OC'] = _val / _lcres['Optical_OC']
136
136
 
137
- if _mass is not None:
138
- for _ky, _val in _df_bsc.items():
139
- _df_ratio[f'{_ky}/PM'] = _val / _mass
137
+ if _mass is not None:
138
+ for _ky, _val in _df_bsc.items():
139
+ _df_ratio[f'{_ky}/PM'] = _val / _mass
140
140
 
141
- _df_ratio[f'Thermal_OC/PM'] = _lcres['Thermal_OC'] / _mass
142
- _df_ratio[f'Thermal_EC/PM'] = _lcres['Thermal_EC'] / _mass
141
+ _df_ratio[f'Thermal_OC/PM'] = _lcres['Thermal_OC'] / _mass
142
+ _df_ratio[f'Thermal_EC/PM'] = _lcres['Thermal_EC'] / _mass
143
143
 
144
- _df_ratio[f'Optical_OC/PM'] = _lcres['Optical_OC'] / _mass
145
- _df_ratio[f'Optical_EC/PM'] = _lcres['Optical_EC'] / _mass
144
+ _df_ratio[f'Optical_OC/PM'] = _lcres['Optical_OC'] / _mass
145
+ _df_ratio[f'Optical_EC/PM'] = _lcres['Optical_EC'] / _mass
146
146
 
147
- ## ratio status
148
- _df_bsc = concat((_lcres, _df_bsc.copy()), axis=1)
147
+ ## ratio status
148
+ _df_bsc = concat((_lcres, _df_bsc.copy()), axis=1)
149
149
 
150
- for _ky, _df in _df_ratio.items():
151
- _df_bsc[f'{_ky}_status'] = 'Normal'
152
- _df_bsc[f'{_ky}_status'] = _df_bsc[f'{_ky}_status'].mask(_df > 1, 'Warning')
150
+ for _ky, _df in _df_ratio.items():
151
+ _df_bsc[f'{_ky}_status'] = 'Normal'
152
+ _df_bsc[f'{_ky}_status'] = _df_bsc[f'{_ky}_status'].mask(_df > 1, 'Warning')
153
153
 
154
- ## out
155
- _out['ratio'] = _df_ratio
156
- _out['basic'] = _df_bsc
154
+ ## out
155
+ _out['ratio'] = _df_ratio
156
+ _out['basic'] = _df_bsc
157
157
 
158
- return _out
158
+ return _out
159
159
 
160
160
 
161
161
  '''
@@ -1,29 +1,30 @@
1
- from pandas import date_range, concat, DataFrame, to_numeric
1
+ from pandas import concat, DataFrame
2
+
2
3
  from ._calculate import _ug2umol
3
4
 
4
5
 
5
6
  def _basic(df_che, nam_lst):
6
- # parameter
7
- df_all = concat(df_che, axis=1)
8
- index = df_all.index.copy()
9
- df_all.columns = nam_lst
7
+ # parameter
8
+ df_all = concat(df_che, axis=1)
9
+ index = df_all.index.copy()
10
+ df_all.columns = nam_lst
10
11
 
11
- df_umol = _ug2umol(df_all)
12
+ df_umol = _ug2umol(df_all)
12
13
 
13
- # calculate
14
- df_out = DataFrame(index=df_umol.index)
14
+ # calculate
15
+ df_out = DataFrame(index=df_umol.index)
15
16
 
16
- # df_out['NTR'] = df_umol['NH4+'] / (df_umol['NH4+'] + df_all['NH3'] / 22.4)
17
- df_out['NTR+'] = df_umol['NH4+'] / (df_umol['NH4+'] + df_umol['NH3'])
17
+ # df_out['NTR'] = df_umol['NH4+'] / (df_umol['NH4+'] + df_all['NH3'] / 22.4)
18
+ df_out['NTR+'] = df_umol['NH4+'] / (df_umol['NH4+'] + df_umol['NH3'])
18
19
 
19
- df_out['NOR'] = df_umol['NO3-'] / (df_umol['NO3-'] + df_umol['NO2'])
20
- df_out['NOR_2'] = (df_umol['NO3-'] + df_umol['HNO3']) / (df_umol['NO3-'] + df_umol['NO2'] + df_umol['HNO3'])
20
+ df_out['NOR'] = df_umol['NO3-'] / (df_umol['NO3-'] + df_umol['NO2'])
21
+ df_out['NOR_2'] = (df_umol['NO3-'] + df_umol['HNO3']) / (df_umol['NO3-'] + df_umol['NO2'] + df_umol['HNO3'])
21
22
 
22
- df_out['SOR'] = df_umol['SO42-'] / (df_umol['SO42-'] + df_umol['SO2'])
23
+ df_out['SOR'] = df_umol['SO42-'] / (df_umol['SO42-'] + df_umol['SO2'])
23
24
 
24
- df_out['epls_NO3-'] = df_umol['NO3-'] / (df_umol['NO3-'] + df_umol['HNO3'])
25
- df_out['epls_NH4+'] = df_umol['NH4+'] / (df_umol['NH4+'] + df_umol['NH3'])
26
- df_out['epls_SO42-'] = df_out['SOR']
27
- df_out['epls_Cl-'] = df_umol['Cl-'] / (df_umol['Cl-'] + df_umol['HCl'])
25
+ df_out['epls_NO3-'] = df_umol['NO3-'] / (df_umol['NO3-'] + df_umol['HNO3'])
26
+ df_out['epls_NH4+'] = df_umol['NH4+'] / (df_umol['NH4+'] + df_umol['NH3'])
27
+ df_out['epls_SO42-'] = df_out['SOR']
28
+ df_out['epls_Cl-'] = df_umol['Cl-'] / (df_umol['Cl-'] + df_umol['HCl'])
28
29
 
29
- return df_out
30
+ return df_out