AeroViz 0.1.5__py3-none-any.whl → 0.1.7__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 (59) hide show
  1. AeroViz/dataProcess/Chemistry/_mass_volume.py +4 -3
  2. AeroViz/dataProcess/Chemistry/_ocec.py +20 -7
  3. AeroViz/dataProcess/Optical/_IMPROVE.py +2 -3
  4. AeroViz/dataProcess/SizeDistr/__init__.py +6 -10
  5. AeroViz/plot/__init__.py +1 -0
  6. AeroViz/plot/meteorology/meteorology.py +2 -0
  7. AeroViz/plot/optical/optical.py +1 -1
  8. AeroViz/plot/pie.py +14 -2
  9. AeroViz/plot/radar.py +184 -0
  10. AeroViz/plot/scatter.py +16 -7
  11. AeroViz/plot/templates/koschmieder.py +11 -8
  12. AeroViz/plot/timeseries/timeseries.py +0 -1
  13. AeroViz/rawDataReader/__init__.py +75 -70
  14. AeroViz/rawDataReader/config/supported_instruments.py +70 -38
  15. AeroViz/rawDataReader/core/__init__.py +208 -178
  16. AeroViz/rawDataReader/script/AE33.py +1 -1
  17. AeroViz/rawDataReader/script/AE43.py +1 -1
  18. AeroViz/rawDataReader/script/APS_3321.py +2 -2
  19. AeroViz/rawDataReader/script/Aurora.py +1 -1
  20. AeroViz/rawDataReader/script/BC1054.py +1 -1
  21. AeroViz/rawDataReader/script/EPA.py +39 -0
  22. AeroViz/rawDataReader/script/GRIMM.py +1 -1
  23. AeroViz/rawDataReader/script/IGAC.py +6 -23
  24. AeroViz/rawDataReader/script/MA350.py +1 -1
  25. AeroViz/rawDataReader/script/Minion.py +102 -30
  26. AeroViz/rawDataReader/script/NEPH.py +1 -1
  27. AeroViz/rawDataReader/script/{Sunset_OCEC.py → OCEC.py} +2 -2
  28. AeroViz/rawDataReader/script/SMPS.py +77 -0
  29. AeroViz/rawDataReader/script/TEOM.py +2 -2
  30. AeroViz/rawDataReader/script/VOC.py +2 -2
  31. AeroViz/rawDataReader/script/XRF.py +11 -0
  32. AeroViz/rawDataReader/script/__init__.py +4 -6
  33. {AeroViz-0.1.5.dist-info → AeroViz-0.1.7.dist-info}/METADATA +57 -32
  34. {AeroViz-0.1.5.dist-info → AeroViz-0.1.7.dist-info}/RECORD +37 -55
  35. AeroViz/process/__init__.py +0 -31
  36. AeroViz/process/core/DataProc.py +0 -19
  37. AeroViz/process/core/SizeDist.py +0 -90
  38. AeroViz/process/core/__init__.py +0 -4
  39. AeroViz/process/method/PyMieScatt_update.py +0 -567
  40. AeroViz/process/method/__init__.py +0 -2
  41. AeroViz/process/method/mie_theory.py +0 -260
  42. AeroViz/process/method/prop.py +0 -62
  43. AeroViz/process/script/AbstractDistCalc.py +0 -143
  44. AeroViz/process/script/Chemical.py +0 -177
  45. AeroViz/process/script/IMPACT.py +0 -49
  46. AeroViz/process/script/IMPROVE.py +0 -161
  47. AeroViz/process/script/Others.py +0 -65
  48. AeroViz/process/script/PSD.py +0 -103
  49. AeroViz/process/script/PSD_dry.py +0 -93
  50. AeroViz/process/script/__init__.py +0 -5
  51. AeroViz/process/script/retrieve_RI.py +0 -69
  52. AeroViz/rawDataReader/script/EPA_vertical.py +0 -46
  53. AeroViz/rawDataReader/script/SMPS_TH.py +0 -41
  54. AeroViz/rawDataReader/script/SMPS_aim11.py +0 -51
  55. AeroViz/rawDataReader/script/SMPS_genr.py +0 -51
  56. AeroViz/rawDataReader/script/Table.py +0 -27
  57. {AeroViz-0.1.5.dist-info → AeroViz-0.1.7.dist-info}/LICENSE +0 -0
  58. {AeroViz-0.1.5.dist-info → AeroViz-0.1.7.dist-info}/WHEEL +0 -0
  59. {AeroViz-0.1.5.dist-info → AeroViz-0.1.7.dist-info}/top_level.txt +0 -0
@@ -1,106 +1,111 @@
1
1
  from datetime import datetime
2
2
  from pathlib import Path
3
3
 
4
+ from pandas import Grouper, Timedelta
5
+
4
6
  from AeroViz.rawDataReader.config.supported_instruments import meta
5
7
  from AeroViz.rawDataReader.script import *
6
8
 
7
9
  __all__ = ['RawDataReader']
8
10
 
11
+ SUPPORTED_INSTRUMENTS = [
12
+ NEPH, Aurora, SMPS, GRIMM, APS_3321, AE33, AE43, BC1054,
13
+ MA350, TEOM, OCEC, IGAC, VOC, EPA, Minion
14
+ ]
15
+
9
16
 
10
17
  def RawDataReader(instrument_name: str,
11
18
  path: Path,
12
- qc: bool = True,
13
- csv_raw: bool = True,
14
19
  reset: bool = False,
15
- rate: bool = False,
20
+ qc: bool | str = True,
21
+ qc_freq: str | None = None,
22
+ rate: bool = True,
16
23
  append_data: bool = False,
17
- start: datetime | None = None,
18
- end: datetime | None = None,
19
- mean_freq='1h',
20
- csv_out=True,
24
+ start: datetime = None,
25
+ end: datetime = None,
26
+ mean_freq: str = '1h',
27
+ csv_out: bool = True,
21
28
  ):
22
29
  """
23
30
  Factory function to instantiate the appropriate reader module for a given instrument and
24
31
  return the processed data over the specified time range.
25
32
 
26
- Parameters
27
- ----------
28
- instrument_name : str
29
- The name of the instrument for which to read data. Must be a valid key in the `meta` dictionary.
30
- path : Path
31
- The directory where raw data files for the instrument are stored.
32
- qc : bool, optional (default=True)
33
- If True, apply quality control (QC) to the raw data.
34
- csv_raw : bool, optional (default=True)
35
- If True, read raw data from CSV files.
36
- reset : bool, optional (default=False)
37
- If True, reset the state and reprocess the data from scratch.
38
- rate : bool, optional (default=False)
39
- If True, calculate rates from the data.
40
- append_data : bool, optional (default=False)
41
- If True, append new data to the existing dataset instead of overwriting it.
42
- start : datetime, optional
43
- Start time for filtering the data. If None, no start time filtering will be applied.
44
- end : datetime, optional
45
- End time for filtering the data. If None, no end time filtering will be applied.
46
- mean_freq : str, optional (default='1h')
47
- Resampling frequency for averaging the data. Example: '1h' for hourly mean.
48
- csv_out : bool, optional (default=True)
49
- If True, output the processed data as a CSV file.
50
-
51
- Return
52
- ------
53
- reader_module : Reader
54
- An instance of the reader module corresponding to the specified instrument, which processes
55
- the data and returns it in a usable format.
56
-
57
- Raises
58
- ------
59
- ValueError
60
- If the `instrument_name` provided is not a valid key in the `meta` dictionary.
61
-
62
- Example
63
- -------
33
+ :param instrument_name: The name of the instrument for which to read data. Must be a valid key in the `meta` dictionary.
34
+ :param path: The directory where raw data files for the instrument are stored.
35
+ :param reset: If True, reset the state and reprocess the data from scratch.
36
+ :param qc: If True, apply quality control (QC) to the raw data.
37
+ :param qc_freq: Frequency at which to perform QC. Must be one of 'W', 'M', 'Q', 'Y' for weekly, monthly, quarterly, or yearly.
38
+ :param rate: If True, calculate rates from the data.
39
+ :param append_data: If True, append new data to the existing dataset instead of overwriting it.
40
+ :param start: Start time for filtering the data. If None, no start time filtering will be applied.
41
+ :param end: End time for filtering the data. If None, no end time filtering will be applied.
42
+ :param mean_freq: Resampling frequency for averaging the data. Example: '1h' for hourly mean.
43
+ :param csv_out: If True, output the processed data as a CSV file.
44
+
45
+ :return: An instance of the reader module corresponding to the specified instrument, which processes the data and returns it in a usable format.
46
+
47
+ :raises ValueError: If the `instrument_name` provided is not a valid key in the `meta` dictionary.
48
+ :raises ValueError: If the specified path does not exist or is not a directory.
49
+ :raises ValueError: If the QC frequency is invalid.
50
+ :raises ValueError: If start and end times are not both provided or are invalid.
51
+ :raises ValueError: If the mean_freq is not a valid frequency string.
52
+
53
+ :Example:
54
+
64
55
  To read and process data for the BC1054 instrument:
65
56
 
66
57
  >>> from pathlib import Path
67
58
  >>> from datetime import datetime
68
- >>> data = RawDataReader(instrument_name='BC1054', path=Path('/path/to/data'),
69
- >>> start=datetime(2024, 1, 1), end=datetime(2024, 2, 1))
59
+ >>>
60
+ >>> data = RawDataReader(
61
+ ... instrument_name='BC1054',
62
+ ... path=Path('/path/to/data'),
63
+ ... start=datetime(2024, 2, 1),
64
+ ... end=datetime(2024, 7, 31, 23))
70
65
  """
71
66
  # Mapping of instrument names to their respective classes
72
- instrument_class_map = {
73
- 'NEPH': NEPH,
74
- 'Aurora': Aurora,
75
- 'SMPS_genr': SMPS_genr,
76
- 'SMPS_aim11': SMPS_aim11,
77
- 'SMPS_TH': SMPS_TH,
78
- 'GRIMM': GRIMM,
79
- 'APS_3321': APS_3321,
80
- 'AE33': AE33,
81
- 'AE43': AE43,
82
- 'BC1054': BC1054,
83
- 'MA350': MA350,
84
- 'TEOM': TEOM,
85
- 'Sunset_OCEC': Sunset_OCEC,
86
- 'IGAC': IGAC,
87
- 'VOC': VOC,
88
- 'Table': Table,
89
- 'EPA_vertical': EPA_vertical,
90
- 'Minion': Minion
91
- # Add other instruments and their corresponding classes here
92
- }
67
+ instrument_class_map = {cls.__name__.split('.')[-1]: cls for cls in SUPPORTED_INSTRUMENTS}
93
68
 
94
69
  # Check if the instrument name is in the map
95
70
  if instrument_name not in meta.keys():
96
71
  raise ValueError(f"Instrument name '{instrument_name}' is not valid. \nMust be one of: {list(meta.keys())}")
97
72
 
73
+ # 檢查 path 是否存在且是一個目錄
74
+ if not isinstance(path, Path):
75
+ path = Path(path)
76
+ if not path.exists() or not path.is_dir():
77
+ raise ValueError(f"The specified path '{path}' does not exist or is not a directory.")
78
+
79
+ # Validate the QC frequency
80
+ if qc_freq is not None:
81
+ try:
82
+ Grouper(freq=qc_freq)
83
+ except ValueError as e:
84
+ raise ValueError(f"Invalid frequency: {qc_freq}. Error: {str(e)}")
85
+ except TypeError as e:
86
+ raise ValueError(f"Invalid frequency type: {qc_freq}. Frequency should be a string.")
87
+
88
+ if start and end:
89
+ if end.hour == 0 and end.minute == 0 and end.second == 0:
90
+ end = end.replace(hour=23)
91
+ else:
92
+ raise ValueError("Both start and end times must be provided.")
93
+ if end <= start:
94
+ raise ValueError(f"Invalid time range: start {start} is after end {end}")
95
+
96
+ # 驗證 mean_freq 的格式是否正確
97
+ try:
98
+ Timedelta(mean_freq)
99
+ except ValueError:
100
+ raise ValueError(
101
+ f"Invalid mean_freq: '{mean_freq}'. It should be a valid frequency string (e.g., '1H', '30min', '1D').")
102
+
98
103
  # Instantiate the class and return the instance
99
104
  reader_module = instrument_class_map[instrument_name].Reader(
100
105
  path=path,
101
- qc=qc,
102
- csv_raw=csv_raw,
103
106
  reset=reset,
107
+ qc=qc,
108
+ qc_freq=qc_freq,
104
109
  rate=rate,
105
110
  append_data=append_data
106
111
  )
@@ -2,76 +2,64 @@
2
2
 
3
3
  meta = {
4
4
  "NEPH": {
5
- "pattern": "*.dat",
5
+ "pattern": ["*.dat"],
6
6
  "freq": "5min",
7
7
  "deter_key": {"Scatter Coe. (550 nm)": ["G"]},
8
8
  },
9
9
 
10
10
  "Aurora": {
11
- "pattern": "*.csv",
11
+ "pattern": ["*.csv"],
12
12
  "freq": "1min",
13
13
  "deter_key": {"Scatter Coe. (550 nm)": ["G"]},
14
14
  },
15
15
 
16
- "SMPS_TH": {
17
- "pattern": "*.txt",
18
- "freq": "6min",
19
- "deter_key": {"Bins": ["all"]},
20
- },
21
-
22
- "SMPS_genr": {
23
- "pattern": "*.txt",
24
- "freq": "6min",
25
- "deter_key": {"Bins": ["all"]},
26
- },
27
-
28
- "SMPS_aim11": {
29
- "pattern": "*.csv",
16
+ "SMPS": {
17
+ "pattern": ["*.txt", "*.csv"],
30
18
  "freq": "6min",
31
19
  "deter_key": {"Bins": ["all"]},
32
20
  },
33
21
 
34
22
  "GRIMM": {
35
- "pattern": "*.dat",
23
+ "pattern": ["*.dat"],
36
24
  "freq": "6min",
37
25
  "deter_key": {"Bins": ["all"]},
38
26
  },
39
27
 
40
28
  "APS_3321": {
41
- "pattern": "*.TXT",
29
+ "pattern": ["*.txt"],
42
30
  "freq": "6min",
43
31
  "deter_key": {"Bins": ["all"]},
44
32
  },
45
33
 
46
34
  "AE33": {
47
- "pattern": "[!ST|!CT|!FV]*[!log]_AE33*.dat",
35
+ "pattern": ["[!ST|!CT|!FV]*[!log]_AE33*.dat"],
48
36
  "freq": "1min",
49
37
  "deter_key": {"BC Mass Conc. (880 nm)": ["BC6"]},
50
38
  "error_state": [],
51
39
  },
52
40
 
53
41
  "AE43": {
54
- "pattern": "[!ST|!CT|!FV]*[!log]_AE43*.dat",
42
+ "pattern": ["[!ST|!CT|!FV]*[!log]_AE43*.dat"],
55
43
  "freq": "1min",
56
44
  "deter_key": {"BC Mass Conc. (880 nm)": ["BC6"]},
57
45
  "error_state": [],
58
46
  },
59
47
 
60
48
  "BC1054": {
61
- "pattern": "*.csv",
49
+ "pattern": ["*.csv"],
62
50
  "freq": "1min",
63
51
  "deter_key": {"BC Mass Conc. (880 nm)": ["BC9"]},
64
52
  "error_state": [1, 2, 4, 8, 16, 32, 65536],
65
53
  },
66
54
 
67
55
  "MA350": {
68
- "pattern": "*.csv",
56
+ "pattern": ["*.csv"],
69
57
  "freq": "1min",
70
58
  "deter_key": {"BC Mass Conc. (880 nm)": ["BC5"]},
71
59
  },
72
60
 
73
61
  "TEOM": {
74
- "pattern": "*.csv",
62
+ "pattern": ["*.csv"],
75
63
  "freq": "6min",
76
64
  "deter_key": {
77
65
  "PM1.0 Mass Conc.": ["PM_Total"],
@@ -79,8 +67,8 @@ meta = {
79
67
  },
80
68
  },
81
69
 
82
- "Sunset_OCEC": {
83
- "pattern": "*LCRes.csv",
70
+ "OCEC": {
71
+ "pattern": ["*LCRes.csv"],
84
72
  "freq": "1h",
85
73
  "deter_key": {
86
74
  "Thermal OC": ["Thermal_OC"],
@@ -91,7 +79,7 @@ meta = {
91
79
  },
92
80
 
93
81
  "IGAC": {
94
- "pattern": "*.csv",
82
+ "pattern": ["*.csv"],
95
83
  "freq": "1h",
96
84
  "deter_key": {
97
85
  "Na+": ["Na+"],
@@ -107,8 +95,55 @@ meta = {
107
95
  },
108
96
  },
109
97
 
98
+ "XRF": {
99
+ "pattern": ["*.csv"],
100
+ "freq": "1h",
101
+ "deter_key": {
102
+ "Al": ["Al"],
103
+ "Si": ["Si"],
104
+ "P": ["P"],
105
+ "S": ["S"],
106
+ "Cl": ["Cl"],
107
+ "K": ["K"],
108
+ "Ca": ["Ca"],
109
+ "Ti": ["Ti"],
110
+ "V": ["V"],
111
+ "Cr": ["Cr"],
112
+ "Mn": ["Mn"],
113
+ "Fe": ["Fe"],
114
+ "Ni": ["Ni"],
115
+ "Cu": ["Cu"],
116
+ "Zn": ["Zn"],
117
+ "As": ["As"],
118
+ "Se": ["Se"],
119
+ "Br": ["Br"],
120
+ "Rb": ["Rb"],
121
+ "Sr": ["Sr"],
122
+ "Y": ["Y"],
123
+ "Zr": ["Zr"],
124
+ "Mo": ["Mo"],
125
+ "Ag": ["Ag"],
126
+ "Cd": ["Cd"],
127
+ "In": ["In"],
128
+ "Sn": ["Sn"],
129
+ "Sb": ["Sb"],
130
+ "Te": ["Te"],
131
+ "Cs": ["Cs"],
132
+ "Ba": ["Ba"],
133
+ "La": ["La"],
134
+ "Ce": ["Ce"],
135
+ "W": ["W"],
136
+ "Pt": ["Pt"],
137
+ "Au": ["Au"],
138
+ "Hg": ["Hg"],
139
+ "Tl": ["Tl"],
140
+ "Pb": ["Pb"],
141
+ "Bi": ["Bi"],
142
+ },
143
+ },
144
+
110
145
  "VOC": {
111
- "pattern": "*.csv",
146
+ "pattern": ["*.csv"],
112
147
  "freq": "1h",
113
148
  "key": [
114
149
  'Benzene', 'Toluene', 'Ethylbenzene', 'm/p-Xylene', 'o-Xylene', 'Ethane', 'Propane', 'Isobutane',
@@ -128,21 +163,18 @@ meta = {
128
163
  "deter_key": None,
129
164
  },
130
165
 
131
- "Table": {
132
- "pattern": "*.csv",
133
- "freq": "1h",
134
- "deter_key": None,
135
- },
136
-
137
- "EPA_vertical": {
138
- "pattern": "*.csv",
166
+ "EPA": {
167
+ "pattern": ["*.csv"],
139
168
  "freq": "1h",
140
- "deter_key": None,
169
+ "deter_key": {"Items": ["all"]},
141
170
  },
142
171
 
143
172
  "Minion": {
144
- "pattern": "*.csv",
173
+ "pattern": ["*.csv", "*.xlsx"],
145
174
  "freq": "1h",
146
- "deter_key": None,
175
+ "deter_key": {
176
+ "Main Salt (Na+, NH4+, Cl-, NO3-, SO42-)": ["Na+", "NH4+", "Cl-", "NO3-", "SO42-"],
177
+ "XRF (Al, Ti, V, Cr, Mn, Fe)": ["Al", "Ti", "V", "Cr", "Mn", "Fe"],
178
+ },
147
179
  },
148
180
  }