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,34 +1,35 @@
1
- from AeroViz.dataProcess.core import _union_index
2
-
3
1
  from datetime import datetime as dtm
2
+
3
+ import numpy as np
4
4
  from pandas import DataFrame, to_datetime
5
5
  # from scipy.interpolate import interp1d
6
6
  from scipy.interpolate import UnivariateSpline as unvpline, interp1d
7
- import numpy as np
7
+
8
+ from AeroViz.dataProcess.core import union_index
8
9
 
9
10
  __all__ = ['merge_SMPS_APS']
10
11
 
11
12
 
12
13
  def __test_plot(smpsx, smps, apsx, aps, mergex, merge, mergeox, mergeo, _sh):
13
- from matplotlib.pyplot import subplots, close, show, rcParams
14
+ from matplotlib.pyplot import subplots, close, show
14
15
 
15
- ## parameter
16
- # '''
17
- ## plot
18
- fig, ax = subplots()
16
+ ## parameter
17
+ # '''
18
+ ## plot
19
+ fig, ax = subplots()
19
20
 
20
- ax.plot(smpsx, smps, c='#ff794c', label='smps', marker='o', lw=2)
21
- ax.plot(apsx, aps, c='#4c79ff', label='aps', marker='o', lw=2)
22
- ax.plot(mergex, merge, c='#79796a', label='merge')
23
- # ax.plot(mergeox,mergeo,c='#111111',label='mergeo',marker='o',lw=.75)
21
+ ax.plot(smpsx, smps, c='#ff794c', label='smps', marker='o', lw=2)
22
+ ax.plot(apsx, aps, c='#4c79ff', label='aps', marker='o', lw=2)
23
+ ax.plot(mergex, merge, c='#79796a', label='merge')
24
+ # ax.plot(mergeox,mergeo,c='#111111',label='mergeo',marker='o',lw=.75)
24
25
 
25
- ax.set(xscale='log', yscale='log', )
26
+ ax.set(xscale='log', yscale='log', )
26
27
 
27
- ax.legend(framealpha=0, )
28
- ax.set_title((_sh ** 2)[0], fontsize=13)
28
+ ax.legend(framealpha=0, )
29
+ ax.set_title((_sh ** 2)[0], fontsize=13)
29
30
 
30
- show()
31
- close()
31
+ show()
32
+ close()
32
33
 
33
34
 
34
35
  # '''
@@ -38,78 +39,78 @@ def __test_plot(smpsx, smps, apsx, aps, mergex, merge, mergeox, mergeo, _sh):
38
39
  ## Create a fitting func. by smps data
39
40
  ## return : shift factor
40
41
  def _overlap_fitting(_smps_ori, _aps_ori, _smps_lb, _aps_hb):
41
- print(f"\t\t{dtm.now().strftime('%m/%d %X')} : \033[92moverlap range fitting\033[0m")
42
+ print(f"\t\t{dtm.now().strftime('%m/%d %X')} : \033[92moverlap range fitting\033[0m")
42
43
 
43
- ## overlap fitting
44
- ## parmeter
45
- _dt_indx = _smps_ori.index
44
+ ## overlap fitting
45
+ ## parmeter
46
+ _dt_indx = _smps_ori.index
46
47
 
47
- ## overlap diameter data
48
- _aps = _aps_ori[_aps_ori.keys()[_aps_ori.keys() < _aps_hb]].copy()
49
- _smps = _smps_ori[_smps_ori.keys()[_smps_ori.keys() > _smps_lb]].copy()
48
+ ## overlap diameter data
49
+ _aps = _aps_ori[_aps_ori.keys()[_aps_ori.keys() < _aps_hb]].copy()
50
+ _smps = _smps_ori[_smps_ori.keys()[_smps_ori.keys() > _smps_lb]].copy()
50
51
 
51
- ## use SMPS data apply power law fitting
52
- ## y = Ax^B, A = e**coefa, B = coefb, x = logx, y = logy
53
- ## ref : http://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
54
- ## power law fit to SMPS num conc at upper bins to log curve
52
+ ## use SMPS data apply power law fitting
53
+ ## y = Ax^B, A = e**coefa, B = coefb, x = logx, y = logy
54
+ ## ref : http://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
55
+ ## power law fit to SMPS num conc at upper bins to log curve
55
56
 
56
- ## coefficient A, B
57
- _smps_qc_cond = ((_smps != 0) & np.isfinite(_smps))
58
- _smps_qc = _smps.where(_smps_qc_cond)
57
+ ## coefficient A, B
58
+ _smps_qc_cond = ((_smps != 0) & np.isfinite(_smps))
59
+ _smps_qc = _smps.where(_smps_qc_cond)
59
60
 
60
- _size = _smps_qc_cond.sum(axis=1)
61
- _size = _size.where(_size != 0.).copy()
61
+ _size = _smps_qc_cond.sum(axis=1)
62
+ _size = _size.where(_size != 0.).copy()
62
63
 
63
- _logx, _logy = np.log(_smps_qc.keys()._data.astype(float)), np.log(_smps_qc)
64
- _x, _y, _xy, _xx = _logx.sum(), _logy.sum(axis=1), (_logx * _logy).sum(axis=1), (_logx ** 2).sum()
64
+ _logx, _logy = np.log(_smps_qc.keys()._data.astype(float)), np.log(_smps_qc)
65
+ _x, _y, _xy, _xx = _logx.sum(), _logy.sum(axis=1), (_logx * _logy).sum(axis=1), (_logx ** 2).sum()
65
66
 
66
- _coeB = ((_size * _xy - _x * _y) / (_size * _xx - _x ** 2.))
67
- _coeA = np.exp((_y - _coeB * _x) / _size).values.reshape(-1, 1)
68
- _coeB = _coeB.values.reshape(-1, 1)
67
+ _coeB = ((_size * _xy - _x * _y) / (_size * _xx - _x ** 2.))
68
+ _coeA = np.exp((_y - _coeB * _x) / _size).values.reshape(-1, 1)
69
+ _coeB = _coeB.values.reshape(-1, 1)
69
70
 
70
- ## rebuild shift smps data by coe. A, B
71
- ## x_shift = (y_ori/A)**(1/B)
72
- _aps_shift_x = (_aps / _coeA) ** (1 / _coeB)
73
- _aps_shift_x = _aps_shift_x.where(np.isfinite(_aps_shift_x))
71
+ ## rebuild shift smps data by coe. A, B
72
+ ## x_shift = (y_ori/A)**(1/B)
73
+ _aps_shift_x = (_aps / _coeA) ** (1 / _coeB)
74
+ _aps_shift_x = _aps_shift_x.where(np.isfinite(_aps_shift_x))
74
75
 
75
- ## the least squares of diameter
76
- ## the shift factor which the cklosest to 1
77
- _shift_factor = (_aps_shift_x.keys()._data.astype(float) / _aps_shift_x)
78
- _shift_factor.columns = range(len(_aps_shift_x.keys()))
76
+ ## the least squares of diameter
77
+ ## the shift factor which the cklosest to 1
78
+ _shift_factor = (_aps_shift_x.keys()._data.astype(float) / _aps_shift_x)
79
+ _shift_factor.columns = range(len(_aps_shift_x.keys()))
79
80
 
80
- _dropna_idx = _shift_factor.dropna(how='all').index.copy()
81
+ _dropna_idx = _shift_factor.dropna(how='all').index.copy()
81
82
 
82
- ## use the target function to get the similar aps and smps bin
83
- ## S2 = sum( (smps_fit_line(dia) - aps(dia*shift_factor) )**2 )
84
- ## assumption : the same diameter between smps and aps should get the same conc.
83
+ ## use the target function to get the similar aps and smps bin
84
+ ## S2 = sum( (smps_fit_line(dia) - aps(dia*shift_factor) )**2 )
85
+ ## assumption : the same diameter between smps and aps should get the same conc.
85
86
 
86
- ## be sure they art in log value
87
- _S2 = DataFrame(index=_aps_shift_x.index)
88
- _dia_table = DataFrame(np.full(_aps_shift_x.shape, _aps_shift_x.keys()),
89
- columns=_aps_shift_x.keys(), index=_aps_shift_x.index)
90
- for _idx, _factor in _shift_factor.items():
91
- _smps_fit_df = _coeA * (_dia_table / _factor.to_frame().values) ** _coeB
92
- _S2[_idx] = ((_smps_fit_df - _aps) ** 2).sum(axis=1)
87
+ ## be sure they art in log value
88
+ _S2 = DataFrame(index=_aps_shift_x.index)
89
+ _dia_table = DataFrame(np.full(_aps_shift_x.shape, _aps_shift_x.keys()),
90
+ columns=_aps_shift_x.keys(), index=_aps_shift_x.index)
91
+ for _idx, _factor in _shift_factor.items():
92
+ _smps_fit_df = _coeA * (_dia_table / _factor.to_frame().values) ** _coeB
93
+ _S2[_idx] = ((_smps_fit_df - _aps) ** 2).sum(axis=1)
93
94
 
94
- _least_squ_idx = _S2.idxmin(axis=1).loc[_dropna_idx]
95
+ _least_squ_idx = _S2.idxmin(axis=1).loc[_dropna_idx]
95
96
 
96
- _shift_factor_out = DataFrame(_shift_factor.loc[_dropna_idx].values[range(len(_dropna_idx)), _least_squ_idx.values],
97
- index=_dropna_idx).reindex(_dt_indx)
97
+ _shift_factor_out = DataFrame(_shift_factor.loc[_dropna_idx].values[range(len(_dropna_idx)), _least_squ_idx.values],
98
+ index=_dropna_idx).reindex(_dt_indx)
98
99
 
99
- return _shift_factor_out, (DataFrame(_coeA, index=_dt_indx), DataFrame(_coeB, index=_dt_indx))
100
+ return _shift_factor_out, (DataFrame(_coeA, index=_dt_indx), DataFrame(_coeB, index=_dt_indx))
100
101
 
101
102
 
102
103
  ## Remove big shift data ()
103
104
  ## Return : aps, smps, shift (without big shift data)
104
105
  def _shift_data_process(_shift):
105
- print(f"\t\t{dtm.now().strftime('%m/%d %X')} : \033[92mshift-data quality control\033[0m")
106
+ print(f"\t\t{dtm.now().strftime('%m/%d %X')} : \033[92mshift-data quality control\033[0m")
106
107
 
107
- _rho = _shift ** 2
108
- _shift = _shift.mask((~np.isfinite(_shift)) | (_rho > 2) | (_rho < 0.3))
108
+ _rho = _shift ** 2
109
+ _shift = _shift.mask((~np.isfinite(_shift)) | (_rho > 2) | (_rho < 0.3))
109
110
 
110
- _qc_index = _shift.mask((_rho < 0.6) | (_shift.isna())).dropna().index
111
+ _qc_index = _shift.mask((_rho < 0.6) | (_shift.isna())).dropna().index
111
112
 
112
- return _qc_index, _shift
113
+ return _qc_index, _shift
113
114
 
114
115
 
115
116
  # return _smps.loc[~_big_shift], _aps.loc[~_big_shift], _shift[~_big_shift].reshape(-1,1)
@@ -119,127 +120,127 @@ def _shift_data_process(_shift):
119
120
  ## shift all smps bin and remove the aps bin which smaller than the latest old smps bin
120
121
  ## Return : merge bins, merge data, density
121
122
  def _merge_data(_smps_ori, _aps_ori, _shift_ori, _smps_lb, _aps_hb, _coe, _shift_mode):
122
- print(f"\t\t{dtm.now().strftime('%m/%d %X')} : \033[92mcreate merge data : {_shift_mode}\033[0m")
123
+ print(f"\t\t{dtm.now().strftime('%m/%d %X')} : \033[92mcreate merge data : {_shift_mode}\033[0m")
123
124
 
124
- _ori_idx = _smps_ori.index
125
- _merge_idx = _smps_ori.loc[_aps_ori.dropna(how='all').index].dropna(how='all').index
125
+ _ori_idx = _smps_ori.index
126
+ _merge_idx = _smps_ori.loc[_aps_ori.dropna(how='all').index].dropna(how='all').index
126
127
 
127
- _corr_aps_cond = _aps_ori.keys() < 700
128
- _corr_aps_ky = _aps_ori.keys()[_corr_aps_cond]
128
+ _corr_aps_cond = _aps_ori.keys() < 700
129
+ _corr_aps_ky = _aps_ori.keys()[_corr_aps_cond]
129
130
 
130
- _uni_idx, _count = np.unique(np.hstack((_smps_ori.dropna(how='all').index, _aps_ori.dropna(how='all').index,
131
- _shift_ori.dropna(how='all').index)), return_counts=True)
131
+ _uni_idx, _count = np.unique(np.hstack((_smps_ori.dropna(how='all').index, _aps_ori.dropna(how='all').index,
132
+ _shift_ori.dropna(how='all').index)), return_counts=True)
132
133
 
133
- _merge_idx = to_datetime(np.unique(_uni_idx[_count == 3]))
134
+ _merge_idx = to_datetime(np.unique(_uni_idx[_count == 3]))
134
135
 
135
- _smps, _aps, _shift = _smps_ori.loc[_merge_idx], _aps_ori.loc[_merge_idx], _shift_ori.loc[_merge_idx].values
136
+ _smps, _aps, _shift = _smps_ori.loc[_merge_idx], _aps_ori.loc[_merge_idx], _shift_ori.loc[_merge_idx].values
136
137
 
137
- ## parameter
138
- _coeA, _coeB = _coe[0].loc[_merge_idx], _coe[1].loc[_merge_idx]
139
- _smps_key, _aps_key = _smps.keys()._data.astype(float), _aps.keys()._data.astype(float)
138
+ ## parameter
139
+ _coeA, _coeB = _coe[0].loc[_merge_idx], _coe[1].loc[_merge_idx]
140
+ _smps_key, _aps_key = _smps.keys()._data.astype(float), _aps.keys()._data.astype(float)
140
141
 
141
- _cntr = 1000
142
- _bin_lb = _smps_key[-1]
142
+ _cntr = 1000
143
+ _bin_lb = _smps_key[-1]
143
144
 
144
- ## make shift bins
145
- _smps_bin = np.full(_smps.shape, _smps_key)
146
- _aps_bin = np.full(_aps.shape, _aps_key)
145
+ ## make shift bins
146
+ _smps_bin = np.full(_smps.shape, _smps_key)
147
+ _aps_bin = np.full(_aps.shape, _aps_key)
147
148
 
148
- _std_bin = np.geomspace(_smps_key[0], _aps_key[-1], 230)
149
- _std_bin_merge = _std_bin[(_std_bin < _cntr) & (_std_bin > _bin_lb)]
150
- _std_bin_inte1 = _std_bin[_std_bin <= _bin_lb]
151
- _std_bin_inte2 = _std_bin[_std_bin >= _cntr]
149
+ _std_bin = np.geomspace(_smps_key[0], _aps_key[-1], 230)
150
+ _std_bin_merge = _std_bin[(_std_bin < _cntr) & (_std_bin > _bin_lb)]
151
+ _std_bin_inte1 = _std_bin[_std_bin <= _bin_lb]
152
+ _std_bin_inte2 = _std_bin[_std_bin >= _cntr]
152
153
 
153
- if _shift_mode == 'mobility':
154
- _aps_bin /= _shift
154
+ if _shift_mode == 'mobility':
155
+ _aps_bin /= _shift
155
156
 
156
- elif _shift_mode == 'aerodynamic':
157
- _smps_bin *= _shift
157
+ elif _shift_mode == 'aerodynamic':
158
+ _smps_bin *= _shift
158
159
 
159
- ## merge
160
- _merge_lst, _corr_lst = [], []
161
- for _bin_smps, _bin_aps, _dt_smps, _dt_aps, _sh in zip(_smps_bin, _aps_bin, _smps.values, _aps.values, _shift):
162
- ## keep complete smps bins and data
163
- ## remove the aps bin data lower than smps bin
164
- _condi = _bin_aps >= _bin_smps[-1]
160
+ ## merge
161
+ _merge_lst, _corr_lst = [], []
162
+ for _bin_smps, _bin_aps, _dt_smps, _dt_aps, _sh in zip(_smps_bin, _aps_bin, _smps.values, _aps.values, _shift):
163
+ ## keep complete smps bins and data
164
+ ## remove the aps bin data lower than smps bin
165
+ _condi = _bin_aps >= _bin_smps[-1]
165
166
 
166
- _merge_bin = np.hstack((_bin_smps, _bin_aps[_condi]))
167
- _merge_dt = np.hstack((_dt_smps, _dt_aps[_condi]))
167
+ _merge_bin = np.hstack((_bin_smps, _bin_aps[_condi]))
168
+ _merge_dt = np.hstack((_dt_smps, _dt_aps[_condi]))
168
169
 
169
- _merge_fit_loc = (_merge_bin < 1500) & (_merge_bin > _smps_lb)
170
+ _merge_fit_loc = (_merge_bin < 1500) & (_merge_bin > _smps_lb)
170
171
 
171
- ## coeA and coeB
172
- _unvpl_fc = unvpline(np.log(_merge_bin[_merge_fit_loc]), np.log(_merge_dt[_merge_fit_loc]), s=50)
173
- _inte_fc = interp1d(_merge_bin, _merge_dt, kind='linear', fill_value='extrapolate')
172
+ ## coeA and coeB
173
+ _unvpl_fc = unvpline(np.log(_merge_bin[_merge_fit_loc]), np.log(_merge_dt[_merge_fit_loc]), s=50)
174
+ _inte_fc = interp1d(_merge_bin, _merge_dt, kind='linear', fill_value='extrapolate')
174
175
 
175
- _merge_dt_fit = np.hstack((_inte_fc(_std_bin_inte1), np.exp(_unvpl_fc(np.log(_std_bin_merge))),
176
- _inte_fc(_std_bin_inte2)))
176
+ _merge_dt_fit = np.hstack((_inte_fc(_std_bin_inte1), np.exp(_unvpl_fc(np.log(_std_bin_merge))),
177
+ _inte_fc(_std_bin_inte2)))
177
178
 
178
- _merge_lst.append(_merge_dt_fit)
179
- _corr_lst.append(interp1d(_std_bin, _merge_dt_fit)(_bin_aps[_corr_aps_cond]))
179
+ _merge_lst.append(_merge_dt_fit)
180
+ _corr_lst.append(interp1d(_std_bin, _merge_dt_fit)(_bin_aps[_corr_aps_cond]))
180
181
 
181
- _df_merge = DataFrame(_merge_lst, columns=_std_bin, index=_merge_idx)
182
- _df_merge = _df_merge.mask(_df_merge < 0)
182
+ _df_merge = DataFrame(_merge_lst, columns=_std_bin, index=_merge_idx)
183
+ _df_merge = _df_merge.mask(_df_merge < 0)
183
184
 
184
- _df_corr = DataFrame(_corr_lst, columns=_corr_aps_ky, index=_merge_idx) / _aps_ori.loc[_merge_idx, _corr_aps_ky]
185
+ _df_corr = DataFrame(_corr_lst, columns=_corr_aps_ky, index=_merge_idx) / _aps_ori.loc[_merge_idx, _corr_aps_ky]
185
186
 
186
- ## process output df
187
- ## average, align with index
188
- def _out_df(*_df_arg, **_df_kwarg):
189
- _df = DataFrame(*_df_arg, **_df_kwarg).reindex(_ori_idx)
190
- _df.index.name = 'time'
191
- return _df
187
+ ## process output df
188
+ ## average, align with index
189
+ def _out_df(*_df_arg, **_df_kwarg):
190
+ _df = DataFrame(*_df_arg, **_df_kwarg).reindex(_ori_idx)
191
+ _df.index.name = 'time'
192
+ return _df
192
193
 
193
- return _out_df(_df_merge), _out_df(_shift_ori ** 2), _out_df(_df_corr)
194
+ return _out_df(_df_merge), _out_df(_shift_ori ** 2), _out_df(_df_corr)
194
195
 
195
196
 
196
197
  def merge_SMPS_APS(df_smps, df_aps, aps_unit='um', smps_overlap_lowbound=500, aps_fit_highbound=1000):
197
- df_smps, df_aps = _union_index(df_smps, df_aps)
198
+ df_smps, df_aps = union_index(df_smps, df_aps)
198
199
 
199
- ## set to the same units
200
- smps, aps_ori = df_smps.copy(), df_aps.copy()
201
- smps.columns = smps.keys().to_numpy(float)
202
- aps_ori.columns = aps_ori.keys().to_numpy(float)
200
+ ## set to the same units
201
+ smps, aps_ori = df_smps.copy(), df_aps.copy()
202
+ smps.columns = smps.keys().to_numpy(float)
203
+ aps_ori.columns = aps_ori.keys().to_numpy(float)
203
204
 
204
- if aps_unit == 'um':
205
- aps_ori.columns = aps_ori.keys() * 1e3
205
+ if aps_unit == 'um':
206
+ aps_ori.columns = aps_ori.keys() * 1e3
206
207
 
207
- den_lst, mer_lst = [], []
208
- aps_input = aps_ori.loc[:, aps_ori.keys() > 700].copy()
208
+ den_lst, mer_lst = [], []
209
+ aps_input = aps_ori.loc[:, aps_ori.keys() > 700].copy()
209
210
 
210
- for _count in range(2):
211
+ for _count in range(2):
211
212
 
212
- ## shift infomation, calculate by powerlaw fitting
213
- shift, coe = _overlap_fitting(smps, aps_input, smps_overlap_lowbound, aps_fit_highbound)
213
+ ## shift infomation, calculate by powerlaw fitting
214
+ shift, coe = _overlap_fitting(smps, aps_input, smps_overlap_lowbound, aps_fit_highbound)
214
215
 
215
- ## process data by shift infomation, and average data
216
- qc_cond, shift = _shift_data_process(shift)
216
+ ## process data by shift infomation, and average data
217
+ qc_cond, shift = _shift_data_process(shift)
217
218
 
218
- ## merge aps and smps
219
- merge_arg = (smps, aps_ori, shift, smps_overlap_lowbound, aps_fit_highbound, coe)
220
- merge_data_mob, density, _corr = _merge_data(*merge_arg, 'mobility')
221
- merge_data_aer, density, _ = _merge_data(*merge_arg, 'aerodynamic')
222
- density.columns = ['density']
219
+ ## merge aps and smps
220
+ merge_arg = (smps, aps_ori, shift, smps_overlap_lowbound, aps_fit_highbound, coe)
221
+ merge_data_mob, density, _corr = _merge_data(*merge_arg, 'mobility')
222
+ merge_data_aer, density, _ = _merge_data(*merge_arg, 'aerodynamic')
223
+ density.columns = ['density']
223
224
 
224
- if _count == 0:
225
- corr = _corr.resample('1d').mean().reindex(smps.index).ffill()
226
- corr = corr.mask(corr < 1, 1)
227
- aps_ori.loc[:, corr.keys()] *= corr
225
+ if _count == 0:
226
+ corr = _corr.resample('1d').mean().reindex(smps.index).ffill()
227
+ corr = corr.mask(corr < 1, 1)
228
+ aps_ori.loc[:, corr.keys()] *= corr
228
229
 
229
- aps_input = aps_ori.copy()
230
+ aps_input = aps_ori.copy()
230
231
 
231
- ## out
232
- out_dic = {
233
- 'data_all': merge_data_mob,
234
- 'data_qc': merge_data_mob.loc[qc_cond],
235
- 'data_all_aer': merge_data_aer,
236
- 'data_qc_aer': merge_data_aer.loc[qc_cond],
237
- 'density_all': density,
238
- 'density_qc': density.loc[qc_cond],
239
- }
232
+ ## out
233
+ out_dic = {
234
+ 'data_all': merge_data_mob,
235
+ 'data_qc': merge_data_mob.loc[qc_cond],
236
+ 'data_all_aer': merge_data_aer,
237
+ 'data_qc_aer': merge_data_aer.loc[qc_cond],
238
+ 'density_all': density,
239
+ 'density_qc': density.loc[qc_cond],
240
+ }
240
241
 
241
- ## process data
242
- for _nam, _df in out_dic.items():
243
- out_dic[_nam] = _df.reindex(smps.index).copy()
242
+ ## process data
243
+ for _nam, _df in out_dic.items():
244
+ out_dic[_nam] = _df.reindex(smps.index).copy()
244
245
 
245
- return out_dic
246
+ return out_dic