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
@@ -7,43 +7,43 @@ from AeroViz.tools.datareader import DataReader
7
7
 
8
8
 
9
9
  class ImpactProc(DataProc):
10
- """
11
- A class for processing impact data.
12
-
13
- Parameters:
14
- -----------
15
- reset : bool, optional
16
- If True, resets the processing. Default is False.
17
- save_filename : str or Path, optional
18
- The name or path to save the processed data. Default is 'IMPACT.csv'.
19
-
20
- Methods:
21
- --------
22
- process_data(reset: bool = False, save_filename: str | Path = 'IMPACT.csv') -> DataFrame:
23
- Process data and save the result.
24
-
25
- save_data(data: DataFrame, save_filename: str | Path):
26
- Save processed data to a file.
27
-
28
- Attributes:
29
- -----------
30
- DEFAULT_PATH : Path
31
- The default path for data files.
32
-
33
- Examples:
34
- ---------
35
- >>> df_custom = ImpactProc().process_data(reset=True, save_filename='custom_file.csv')
36
- """
37
-
38
- def __init__(self, file_paths: list[Path | str] = None):
39
- super().__init__()
40
- self.file_paths = [Path(fp) for fp in file_paths]
41
-
42
- def process_data(self, reset: bool = False, save_file: Path | str = None) -> DataFrame:
43
- save_file = Path(save_file)
44
- if save_file.exists() and not reset:
45
- return read_csv(save_file, parse_dates=['Time'], index_col='Time')
46
- else:
47
- _df = concat([DataReader(file) for file in self.file_paths], axis=1)
48
- _df.to_csv(save_file)
49
- return _df
10
+ """
11
+ A class for processing impact data.
12
+
13
+ Parameters:
14
+ -----------
15
+ reset : bool, optional
16
+ If True, resets the processing. Default is False.
17
+ save_filename : str or Path, optional
18
+ The name or path to save the processed data. Default is 'IMPACT.csv'.
19
+
20
+ Methods:
21
+ --------
22
+ process_data(reset: bool = False, save_filename: str | Path = 'IMPACT.csv') -> DataFrame:
23
+ Process data and save the result.
24
+
25
+ save_data(data: DataFrame, save_filename: str | Path):
26
+ Save processed data to a file.
27
+
28
+ Attributes:
29
+ -----------
30
+ DEFAULT_PATH : Path
31
+ The default path for data files.
32
+
33
+ Examples:
34
+ ---------
35
+ >>> df_custom = ImpactProc().process_data(reset=True, save_filename='custom_file.csv')
36
+ """
37
+
38
+ def __init__(self, file_paths: list[Path | str] = None):
39
+ super().__init__()
40
+ self.file_paths = [Path(fp) for fp in file_paths]
41
+
42
+ def process_data(self, reset: bool = False, save_file: Path | str = None) -> DataFrame:
43
+ save_file = Path(save_file)
44
+ if save_file.exists() and not reset:
45
+ return read_csv(save_file, parse_dates=['Time'], index_col='Time')
46
+ else:
47
+ _df = concat([DataReader(file) for file in self.file_paths], axis=1)
48
+ _df.to_csv(save_file)
49
+ return _df
@@ -1,6 +1,6 @@
1
+ from pathlib import Path
1
2
  from typing import Literal
2
3
 
3
- from pathlib import Path
4
4
  from pandas import read_csv, concat, read_json
5
5
 
6
6
  from AeroViz.process.core import DataProc
@@ -8,154 +8,154 @@ from AeroViz.tools.datareader import DataReader
8
8
 
9
9
 
10
10
  class ImproveProc(DataProc):
11
- """
12
- A class for process improved chemical data.
13
-
14
- Parameters:
15
- -----------
16
- reset : bool, optional
17
- If True, resets the process. Default is False.
18
- filename : str, optional
19
- The name of the file to process. Default is None.
20
- version : str, optional
21
- The version of the data process. Should be one of 'revised' or 'modified'.
22
- Default is None.
23
-
24
- Methods:
25
- --------
26
- revised(_df):
27
- Calculate revised version of particle contribution.
28
-
29
- modified(_df):
30
- Calculate modified version of particle contribution.
31
-
32
- gas(_df):
33
- Calculate gas contribution.
34
-
35
- frh(_RH, version=None):
36
- Helper function to get frh values based on relative humidity (RH) and version.
37
-
38
- process_data():
39
- Process data and save the result.
40
-
41
- Attributes:
42
- -----------
43
- DEFAULT_PATH : Path
44
- The default path for data files.
45
-
46
- Examples:
47
- ---------
48
- >>> df = ImproveProc(reset=True, filename='revised_IMPROVE.csv', version='revised').process_data()
49
-
50
- """
51
-
52
- def __init__(self, file_paths: list[Path | str] = None):
53
- super().__init__()
54
- self.file_paths = [Path(fp) for fp in file_paths]
55
-
56
- @staticmethod
57
- def frh(_RH):
58
- _frh = read_json(Path(__file__).parent.parent.parent / 'plot' / 'utils' / 'fRH.json')
59
- if _RH is not None:
60
- if _RH > 95:
61
- _RH = 95
62
- _RH = round(_RH)
63
- return _frh.loc[_RH].values.T
64
-
65
- return 1, 1, 1, 1
66
-
67
- def revised(self, _df):
68
- def mode(Mass):
69
- L_mode = Mass ** 2 / 20 if Mass < 20 else Mass
70
- S_mode = Mass - L_mode if Mass < 20 else 0
71
-
72
- return L_mode, S_mode
73
-
74
- _frh, _frhss, _frhs, _frhl = self.frh(_df['RH'])
75
-
76
- L_AS, S_AS = mode(_df['AS'])
77
- L_AN, S_AN = mode(_df['AN'])
78
- L_OM, S_OM = mode(_df['OM'])
79
-
80
- _df['AS_ext_dry'] = 2.2 * 1 * S_AS + 4.8 * 1 * L_AS
81
- _df['AN_ext_dry'] = 2.4 * 1 * S_AN + 5.1 * 1 * L_AN
82
- _df['OM_ext_dry'] = 2.8 * S_OM + 6.1 * L_OM
83
- _df['Soil_ext_dry'] = 1 * _df['Soil']
84
- _df['SS_ext_dry'] = 1.7 * 1 * _df['SS']
85
- _df['EC_ext_dry'] = 10 * _df['EC']
86
- _df['total_ext_dry'] = sum(_df['AS_ext_dry':'EC_ext_dry'])
87
-
88
- _df['AS_ext'] = (2.2 * _frhs * S_AS) + (4.8 * _frhl * L_AS)
89
- _df['AN_ext'] = (2.4 * _frhs * S_AN) + (5.1 * _frhl * L_AN)
90
- _df['OM_ext'] = (2.8 * S_OM) + (6.1 * L_OM)
91
- _df['Soil_ext'] = (1 * _df['Soil'])
92
- _df['SS_ext'] = (1.7 * _frhss * _df['SS'])
93
- _df['EC_ext'] = (10 * _df['EC'])
94
- _df['total_ext'] = sum(_df['AS_ext':'EC_ext'])
95
-
96
- _df['ALWC_AS_ext'] = _df['AS_ext'] - _df['AS_ext_dry']
97
- _df['ALWC_AN_ext'] = _df['AN_ext'] - _df['AN_ext_dry']
98
- _df['ALWC_SS_ext'] = _df['SS_ext'] - _df['SS_ext_dry']
99
- _df['ALWC_ext'] = _df['total_ext'] - _df['total_ext_dry']
100
-
101
- _df['fRH_IMPR'] = _df['total_ext'] / _df['total_ext_dry']
102
-
103
- return _df['AS_ext_dry':]
104
-
105
- def modified(self, _df):
106
- _frh, _frhss, _frhs, _frhl = self.frh(_df['RH'])
107
-
108
- _df['AS_ext_dry'] = 3 * 1 * _df['AS']
109
- _df['AN_ext_dry'] = 3 * 1 * _df['AN']
110
- _df['OM_ext_dry'] = 4 * _df['OM']
111
- _df['Soil_ext_dry'] = 1 * _df['Soil']
112
- _df['SS_ext_dry'] = 1.7 * 1 * _df['SS']
113
- _df['EC_ext_dry'] = 10 * _df['EC']
114
- _df['total_ext_dry'] = sum(_df['AS_ext_dry':'EC_ext_dry'])
115
-
116
- _df['AS_ext'] = (3 * _frh * _df['AS'])
117
- _df['AN_ext'] = (3 * _frh * _df['AN'])
118
- _df['OM_ext'] = (4 * _df['OM'])
119
- _df['Soil_ext'] = (1 * _df['Soil'])
120
- _df['SS_ext'] = (1.7 * _frhss * _df['SS'])
121
- _df['EC_ext'] = (10 * _df['EC'])
122
- _df['total_ext'] = sum(_df['AS_ext':'EC_ext'])
123
-
124
- _df['ALWC_AS_ext'] = _df['AS_ext'] - _df['AS_ext_dry']
125
- _df['ALWC_AN_ext'] = _df['AN_ext'] - _df['AN_ext_dry']
126
- _df['ALWC_SS_ext'] = _df['SS_ext'] - _df['SS_ext_dry']
127
- _df['ALWC_ext'] = _df['total_ext'] - _df['total_ext_dry']
128
-
129
- _df['fRH_IMPR'] = _df['total_ext'] / _df['total_ext_dry']
130
-
131
- return _df['AS_ext_dry':]
132
-
133
- @staticmethod
134
- def gas(_df):
135
- _df['ScatteringByGas'] = (11.4 * 293 / (273 + _df['AT']))
136
- _df['AbsorptionByGas'] = (0.33 * _df['NO2'])
137
- _df['ExtinctionByGas'] = _df['ScatteringByGas'] + _df['AbsorptionByGas']
138
- return _df['ScatteringByGas':]
139
-
140
- def process_data(self, reset: bool = False, save_file: Path | str = None,
141
- version: Literal["revised", "modified"] = "revised"):
142
- save_file = Path(save_file)
143
- if save_file.exists() and not reset:
144
- return read_csv(save_file, parse_dates=['Time'], index_col='Time')
145
- else:
146
- # data_files = ['EPB.csv', 'IMPACT.csv', 'chemical.csv']
147
- df = concat([DataReader(file) for file in self.file_paths], axis=1)
148
-
149
- # particle contribution '銨不足不納入計算'
150
- improve_input_df = df.loc[df['NH4_status'] != 'Deficiency', ['AS', 'AN', 'OM', 'Soil', 'SS', 'EC', 'RH']]
151
-
152
- df_improve = improve_input_df.dropna().copy().apply(self.revised if version == 'revised' else self.modified,
153
- axis=1)
154
-
155
- # gas contribution
156
- df_ext_gas = df[['NO2', 'AT']].dropna().copy().apply(self.gas, axis=1)
157
-
158
- _df = concat([df_improve, df_ext_gas], axis=1).reindex(df.index.copy())
159
- _df.to_csv(save_file)
160
-
161
- return _df
11
+ """
12
+ A class for process improved chemical data.
13
+
14
+ Parameters:
15
+ -----------
16
+ reset : bool, optional
17
+ If True, resets the process. Default is False.
18
+ filename : str, optional
19
+ The name of the file to process. Default is None.
20
+ version : str, optional
21
+ The version of the data process. Should be one of 'revised' or 'modified'.
22
+ Default is None.
23
+
24
+ Methods:
25
+ --------
26
+ revised(_df):
27
+ Calculate revised version of particle contribution.
28
+
29
+ modified(_df):
30
+ Calculate modified version of particle contribution.
31
+
32
+ gas(_df):
33
+ Calculate gas contribution.
34
+
35
+ frh(_RH, version=None):
36
+ Helper function to get frh values based on relative humidity (RH) and version.
37
+
38
+ process_data():
39
+ Process data and save the result.
40
+
41
+ Attributes:
42
+ -----------
43
+ DEFAULT_PATH : Path
44
+ The default path for data files.
45
+
46
+ Examples:
47
+ ---------
48
+ >>> df = ImproveProc(reset=True, filename='revised_IMPROVE.csv', version='revised').process_data()
49
+
50
+ """
51
+
52
+ def __init__(self, file_paths: list[Path | str] = None):
53
+ super().__init__()
54
+ self.file_paths = [Path(fp) for fp in file_paths]
55
+
56
+ @staticmethod
57
+ def frh(_RH):
58
+ _frh = read_json(Path(__file__).parent.parent.parent / 'plot' / 'utils' / 'fRH.json')
59
+ if _RH is not None:
60
+ if _RH > 95:
61
+ _RH = 95
62
+ _RH = round(_RH)
63
+ return _frh.loc[_RH].values.T
64
+
65
+ return 1, 1, 1, 1
66
+
67
+ def revised(self, _df):
68
+ def mode(Mass):
69
+ L_mode = Mass ** 2 / 20 if Mass < 20 else Mass
70
+ S_mode = Mass - L_mode if Mass < 20 else 0
71
+
72
+ return L_mode, S_mode
73
+
74
+ _frh, _frhss, _frhs, _frhl = self.frh(_df['RH'])
75
+
76
+ L_AS, S_AS = mode(_df['AS'])
77
+ L_AN, S_AN = mode(_df['AN'])
78
+ L_OM, S_OM = mode(_df['OM'])
79
+
80
+ _df['AS_ext_dry'] = 2.2 * 1 * S_AS + 4.8 * 1 * L_AS
81
+ _df['AN_ext_dry'] = 2.4 * 1 * S_AN + 5.1 * 1 * L_AN
82
+ _df['OM_ext_dry'] = 2.8 * S_OM + 6.1 * L_OM
83
+ _df['Soil_ext_dry'] = 1 * _df['Soil']
84
+ _df['SS_ext_dry'] = 1.7 * 1 * _df['SS']
85
+ _df['EC_ext_dry'] = 10 * _df['EC']
86
+ _df['total_ext_dry'] = sum(_df['AS_ext_dry':'EC_ext_dry'])
87
+
88
+ _df['AS_ext'] = (2.2 * _frhs * S_AS) + (4.8 * _frhl * L_AS)
89
+ _df['AN_ext'] = (2.4 * _frhs * S_AN) + (5.1 * _frhl * L_AN)
90
+ _df['OM_ext'] = (2.8 * S_OM) + (6.1 * L_OM)
91
+ _df['Soil_ext'] = (1 * _df['Soil'])
92
+ _df['SS_ext'] = (1.7 * _frhss * _df['SS'])
93
+ _df['EC_ext'] = (10 * _df['EC'])
94
+ _df['total_ext'] = sum(_df['AS_ext':'EC_ext'])
95
+
96
+ _df['ALWC_AS_ext'] = _df['AS_ext'] - _df['AS_ext_dry']
97
+ _df['ALWC_AN_ext'] = _df['AN_ext'] - _df['AN_ext_dry']
98
+ _df['ALWC_SS_ext'] = _df['SS_ext'] - _df['SS_ext_dry']
99
+ _df['ALWC_ext'] = _df['total_ext'] - _df['total_ext_dry']
100
+
101
+ _df['fRH_IMPR'] = _df['total_ext'] / _df['total_ext_dry']
102
+
103
+ return _df['AS_ext_dry':]
104
+
105
+ def modified(self, _df):
106
+ _frh, _frhss, _frhs, _frhl = self.frh(_df['RH'])
107
+
108
+ _df['AS_ext_dry'] = 3 * 1 * _df['AS']
109
+ _df['AN_ext_dry'] = 3 * 1 * _df['AN']
110
+ _df['OM_ext_dry'] = 4 * _df['OM']
111
+ _df['Soil_ext_dry'] = 1 * _df['Soil']
112
+ _df['SS_ext_dry'] = 1.7 * 1 * _df['SS']
113
+ _df['EC_ext_dry'] = 10 * _df['EC']
114
+ _df['total_ext_dry'] = sum(_df['AS_ext_dry':'EC_ext_dry'])
115
+
116
+ _df['AS_ext'] = (3 * _frh * _df['AS'])
117
+ _df['AN_ext'] = (3 * _frh * _df['AN'])
118
+ _df['OM_ext'] = (4 * _df['OM'])
119
+ _df['Soil_ext'] = (1 * _df['Soil'])
120
+ _df['SS_ext'] = (1.7 * _frhss * _df['SS'])
121
+ _df['EC_ext'] = (10 * _df['EC'])
122
+ _df['total_ext'] = sum(_df['AS_ext':'EC_ext'])
123
+
124
+ _df['ALWC_AS_ext'] = _df['AS_ext'] - _df['AS_ext_dry']
125
+ _df['ALWC_AN_ext'] = _df['AN_ext'] - _df['AN_ext_dry']
126
+ _df['ALWC_SS_ext'] = _df['SS_ext'] - _df['SS_ext_dry']
127
+ _df['ALWC_ext'] = _df['total_ext'] - _df['total_ext_dry']
128
+
129
+ _df['fRH_IMPR'] = _df['total_ext'] / _df['total_ext_dry']
130
+
131
+ return _df['AS_ext_dry':]
132
+
133
+ @staticmethod
134
+ def gas(_df):
135
+ _df['ScatteringByGas'] = (11.4 * 293 / (273 + _df['AT']))
136
+ _df['AbsorptionByGas'] = (0.33 * _df['NO2'])
137
+ _df['ExtinctionByGas'] = _df['ScatteringByGas'] + _df['AbsorptionByGas']
138
+ return _df['ScatteringByGas':]
139
+
140
+ def process_data(self, reset: bool = False, save_file: Path | str = None,
141
+ version: Literal["revised", "modified"] = "revised"):
142
+ save_file = Path(save_file)
143
+ if save_file.exists() and not reset:
144
+ return read_csv(save_file, parse_dates=['Time'], index_col='Time')
145
+ else:
146
+ # data_files = ['EPB.csv', 'IMPACT.csv', 'chemical.csv']
147
+ df = concat([DataReader(file) for file in self.file_paths], axis=1)
148
+
149
+ # particle contribution '銨不足不納入計算'
150
+ improve_input_df = df.loc[df['NH4_status'] != 'Deficiency', ['AS', 'AN', 'OM', 'Soil', 'SS', 'EC', 'RH']]
151
+
152
+ df_improve = improve_input_df.dropna().copy().apply(self.revised if version == 'revised' else self.modified,
153
+ axis=1)
154
+
155
+ # gas contribution
156
+ df_ext_gas = df[['NO2', 'AT']].dropna().copy().apply(self.gas, axis=1)
157
+
158
+ _df = concat([df_improve, df_ext_gas], axis=1).reindex(df.index.copy())
159
+ _df.to_csv(save_file)
160
+
161
+ return _df
@@ -8,58 +8,58 @@ from AeroViz.tools.datareader import DataReader
8
8
 
9
9
 
10
10
  class OthersProc(DataProc):
11
- """
12
- A class for process impact data.
11
+ """
12
+ A class for process impact data.
13
13
 
14
- Parameters:
15
- -----------
16
- reset : bool, optional
17
- If True, resets the process. Default is False.
18
- filename : str, optional
19
- The name of the file to process. Default is None.
14
+ Parameters:
15
+ -----------
16
+ reset : bool, optional
17
+ If True, resets the process. Default is False.
18
+ filename : str, optional
19
+ The name of the file to process. Default is None.
20
20
 
21
- Methods:
22
- --------
23
- process_data():
24
- Process data and save the result.
21
+ Methods:
22
+ --------
23
+ process_data():
24
+ Process data and save the result.
25
25
 
26
- Attributes:
27
- -----------
28
- DEFAULT_PATH : Path
29
- The default path for data files.
26
+ Attributes:
27
+ -----------
28
+ DEFAULT_PATH : Path
29
+ The default path for data files.
30
30
 
31
- Examples:
32
- ---------
33
- >>> df = OthersProc().process_data(reset=True, filename=None)
31
+ Examples:
32
+ ---------
33
+ >>> df = OthersProc().process_data(reset=True, filename=None)
34
34
 
35
- """
35
+ """
36
36
 
37
- def __init__(self, file_paths: Path | list[Path | str] = None):
38
- super().__init__()
39
- self.file_paths = [Path(fp) for fp in file_paths]
37
+ def __init__(self, file_paths: Path | list[Path | str] = None):
38
+ super().__init__()
39
+ self.file_paths = [Path(fp) for fp in file_paths]
40
40
 
41
- def process_data(self, reset: bool = False, save_file: Path | str = None) -> DataFrame:
42
- save_file = Path(save_file)
43
- if save_file.exists() and not reset:
44
- return read_csv(save_file, parse_dates=['Time'], index_col='Time')
45
- else:
46
- df = concat([DataReader(file) for file in self.file_paths], axis=1)
41
+ def process_data(self, reset: bool = False, save_file: Path | str = None) -> DataFrame:
42
+ save_file = Path(save_file)
43
+ if save_file.exists() and not reset:
44
+ return read_csv(save_file, parse_dates=['Time'], index_col='Time')
45
+ else:
46
+ df = concat([DataReader(file) for file in self.file_paths], axis=1)
47
47
 
48
- results = DataFrame(index=df.index)
48
+ results = DataFrame(index=df.index)
49
49
 
50
- results['PG'] = df[
51
- ['Scattering', 'Absorption', 'ScatteringByGas', 'AbsorptionByGas']].dropna().copy().apply(np.sum,
52
- axis=1)
53
- results['MAC'] = df['Absorption'] / df['T_EC']
54
- results['Ox'] = df['NO2'] + df['O3']
55
- results['N2O5_tracer'] = df['NO2'] * df['O3']
56
- results['Vis_cal'] = 1096 / df['Extinction']
57
- # results['fRH_Mix'] = df['Bext'] / df['Extinction']
58
- # results['fRH_PNSD'] = df['Bext_internal'] / df['Bext_dry']
59
- results['fRH_IMPR'] = df['total_ext'] / df['total_ext_dry']
60
- results['OCEC_ratio'] = df['O_OC'] / df['O_EC']
61
- results['PM1/PM25'] = np.where(df['PM1'] / df['PM25'] < 1, df['PM1'] / df['PM25'], np.nan)
62
- # results['MEE_PNSD'] = df['Bext_internal'] / df['PM25']
63
- # results['MEE_dry_PNSD'] = df['Bext_dry'] / df['PM25']
50
+ results['PG'] = df[
51
+ ['Scattering', 'Absorption', 'ScatteringByGas', 'AbsorptionByGas']].dropna().copy().apply(np.sum,
52
+ axis=1)
53
+ results['MAC'] = df['Absorption'] / df['T_EC']
54
+ results['Ox'] = df['NO2'] + df['O3']
55
+ results['N2O5_tracer'] = df['NO2'] * df['O3']
56
+ results['Vis_cal'] = 1096 / df['Extinction']
57
+ # results['fRH_Mix'] = df['Bext'] / df['Extinction']
58
+ # results['fRH_PNSD'] = df['Bext_internal'] / df['Bext_dry']
59
+ results['fRH_IMPR'] = df['total_ext'] / df['total_ext_dry']
60
+ results['OCEC_ratio'] = df['O_OC'] / df['O_EC']
61
+ results['PM1/PM25'] = np.where(df['PM1'] / df['PM2.5'] < 1, df['PM1'] / df['PM2.5'], np.nan)
62
+ # results['MEE_PNSD'] = df['Bext_internal'] / df['PM25']
63
+ # results['MEE_dry_PNSD'] = df['Bext_dry'] / df['PM25']
64
64
 
65
- return results
65
+ return results
@@ -9,32 +9,32 @@ from AeroViz.process.script.AbstractDistCalc import DistributionCalculator
9
9
 
10
10
  class ParticleSizeDistProc(DataProc):
11
11
  """
12
- A class for process particle size distribution (PSD) data.
13
-
14
- Parameters
15
- ----------
16
- filename : str, optional
17
- The name of the PSD data file.
18
- Defaults to 'PNSD_dNdlogdp.csv' in the default path.
19
-
20
- Attributes
21
- ----------
22
- file_path : Path
23
- The directory path where the PSD data file is located.
24
-
25
- psd : SizeDist
26
- The SizeDist object.
27
-
28
- Methods
29
- -------
30
- process_data(filename='PSD.csv')
31
- Process and save overall PSD properties.
32
-
33
- Examples
34
- --------
35
- Example 1: Use default path and filename
36
- >>> psd_data = ParticleSizeDistProc(filename='PNSD_dNdlogdp.csv').process_data(reset=True)
37
- """
12
+ A class for process particle size distribution (PSD) data.
13
+
14
+ Parameters
15
+ ----------
16
+ filename : str, optional
17
+ The name of the PSD data file.
18
+ Defaults to 'PNSD_dNdlogdp.csv' in the default path.
19
+
20
+ Attributes
21
+ ----------
22
+ file_path : Path
23
+ The directory path where the PSD data file is located.
24
+
25
+ psd : SizeDist
26
+ The SizeDist object.
27
+
28
+ Methods
29
+ -------
30
+ process_data(filename='PSD.csv')
31
+ Process and save overall PSD properties.
32
+
33
+ Examples
34
+ --------
35
+ Example 1: Use default path and filename
36
+ >>> psd_data = ParticleSizeDistProc(filename='PNSD_dNdlogdp.csv').process_data(reset=True)
37
+ """
38
38
 
39
39
  def __init__(self, file_path: Path | str = None):
40
40
  super().__init__()