UAVision 1.0.0__tar.gz

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.
uavision-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019-2025 Finnish Meteorological Institute
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ include src/UAVision\bin_edges/*.txt
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: UAVision
3
+ Version: 1.0.0
4
+ Summary: UAV instrument data processing
5
+ Author-email: VIET LE <viet.le@fmi.fi>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2019-2025 Finnish Meteorological Institute
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Requires-Python: >=3.11
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy
31
+ Requires-Dist: matplotlib
32
+ Requires-Dist: pandas
33
+ Dynamic: license-file
34
+
35
+ # UAVision
36
+ UAVision is a Python package for UAV instrument data processing (particle counters, BME sensors, POPS, mCDA, OPC).
37
+ It provides preprocessing utilities, concentration calculations.
38
+
39
+ ## Features
40
+ - Preprocessing and derived metrics for MCDA, POPS and other instruments.
41
+ - OPC / Mavic helpers for concentration and lag calculations.
42
+ - Included bin-edge resources for common instruments (mcda, pops, opc).
43
+ - For mcda, there are 4 options for sizes: ['PSL_0.6-40', 'PSL_0.15-17', 'water_0.6-40', 'water_0.15-17']
44
+
45
+ ## Key modules (examples)
46
+ - UAVision.preprocess — functions like preprocess_mcda, preprocess_pops, calculate_height_df.
47
+ - UAVision.mavic.preprocess — functions like calculate_concentration, calculate_lag.
48
+ - Package data: /bin_edges/*.txt
49
+
50
+ ## Example usage
51
+ ```sh
52
+ from UAVision.preprocess import preprocess_mcda
53
+ df = preprocess_mcda("data_path/datafile.csv", size="water_0.15-17")
54
+ ```
55
+ # Notes
56
+ Bin-edge files are included as package data and can be loaded with importlib.resources. See pyproject.toml for packaging metadata.
57
+
58
+ # Contributing / Contact
59
+ Author: viet.le@fmi.fi — pull requests and bug reports welcome.
@@ -0,0 +1,25 @@
1
+ # UAVision
2
+ UAVision is a Python package for UAV instrument data processing (particle counters, BME sensors, POPS, mCDA, OPC).
3
+ It provides preprocessing utilities, concentration calculations.
4
+
5
+ ## Features
6
+ - Preprocessing and derived metrics for MCDA, POPS and other instruments.
7
+ - OPC / Mavic helpers for concentration and lag calculations.
8
+ - Included bin-edge resources for common instruments (mcda, pops, opc).
9
+ - For mcda, there are 4 options for sizes: ['PSL_0.6-40', 'PSL_0.15-17', 'water_0.6-40', 'water_0.15-17']
10
+
11
+ ## Key modules (examples)
12
+ - UAVision.preprocess — functions like preprocess_mcda, preprocess_pops, calculate_height_df.
13
+ - UAVision.mavic.preprocess — functions like calculate_concentration, calculate_lag.
14
+ - Package data: /bin_edges/*.txt
15
+
16
+ ## Example usage
17
+ ```sh
18
+ from UAVision.preprocess import preprocess_mcda
19
+ df = preprocess_mcda("data_path/datafile.csv", size="water_0.15-17")
20
+ ```
21
+ # Notes
22
+ Bin-edge files are included as package data and can be loaded with importlib.resources. See pyproject.toml for packaging metadata.
23
+
24
+ # Contributing / Contact
25
+ Author: viet.le@fmi.fi — pull requests and bug reports welcome.
@@ -0,0 +1,16 @@
1
+ [build-system]
2
+ requires = ["setuptools>=75", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "UAVision"
7
+ version = "1.0.0"
8
+ description = "UAV instrument data processing"
9
+ readme = "README.md"
10
+ authors = [{ name = "VIET LE", email = "viet.le@fmi.fi" }]
11
+ license = { file = "LICENSE" }
12
+ requires-python = ">=3.11"
13
+ dependencies = ["numpy", "matplotlib", "pandas"]
14
+
15
+ [tool.setuptools.packages.find]
16
+ where = ["src/"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ {"PSL_0.6-40": [0.244381, 0.246646, 0.248908, 0.251144, 0.253398, 0.255593, 0.257846, 0.260141, 0.262561, 0.265062, 0.267712, 0.27037, 0.273159, 0.275904, 0.278724, 0.281554, 0.284585, 0.287661, 0.290892, 0.294127, 0.297512, 0.300813, 0.304101, 0.307439, 0.310919, 0.314493, 0.318336, 0.322265, 0.326283, 0.330307, 0.334409, 0.338478, 0.342743, 0.347102, 0.351648, 0.356225, 0.360972, 0.365856, 0.371028, 0.376344, 0.382058, 0.387995, 0.394223, 0.400632, 0.407341, 0.414345, 0.42174, 0.429371, 0.437556, 0.446036, 0.454738, 0.463515, 0.472572, 0.481728, 0.491201, 0.500739, 0.510645, 0.52072, 0.530938, 0.541128, 0.551563, 0.562058, 0.572951, 0.583736, 0.594907, 0.606101, 0.617542, 0.628738, 0.640375, 0.652197, 0.664789, 0.677657, 0.691517, 0.705944, 0.721263, 0.736906, 0.753552, 0.770735, 0.789397, 0.80869, 0.82951, 0.851216, 0.874296, 0.897757, 0.922457, 0.948074, 0.975372, 1.003264, 1.033206, 1.064365, 1.09709, 1.130405, 1.165455, 1.201346, 1.239589, 1.278023, 1.318937, 1.360743, 1.403723, 1.446, 1.489565, 1.532676, 1.577436, 1.621533, 1.667088, 1.71252, 1.758571, 1.802912, 1.847836, 1.891948, 1.937088, 1.981087, 2.027604, 2.074306, 2.121821, 2.168489, 2.216644, 2.263724, 2.312591, 2.361099, 2.41222, 2.464198, 2.518098, 2.571786, 2.628213, 2.685162, 2.745035, 2.80545, 2.869842, 2.935997, 3.005175, 3.074905, 3.148598, 3.224051, 3.305016, 3.387588, 3.476382, 3.568195, 3.664863, 3.761628, 3.863183, 3.965651, 4.07283, 4.17905, 4.289743, 4.400463, 4.512449, 4.621025, 4.73153, 4.83992, 4.949855, 5.057777, 5.169742, 5.281416, 5.395039, 5.506828, 5.621488, 5.734391, 5.849553, 5.962881, 6.081516, 6.200801, 6.322133, 6.441786, 6.56513, 6.686935, 6.813017, 6.938981, 7.071558, 7.205968, 7.345185, 7.483423, 7.628105, 7.774385, 7.926945, 8.0805, 8.247832, 8.419585, 8.598929, 8.780634, 8.973158, 9.167022, 9.37276, 9.582145, 9.808045, 10.041607, 10.287848, 10.537226, 10.801172, 11.068405, 11.345135, 11.621413, 11.910639, 12.200227, 12.492929, 12.780176, 13.072476, 13.359067, 13.651163, 13.937329, 14.232032, 14.523919, 14.819204, 15.106612, 15.40211, 15.695489, 15.998035, 16.297519, 16.610927, 16.9268, 17.250511, 17.570901, 17.904338, 18.239874, 18.588605, 18.938763, 19.311505, 19.693678, 20.093464, 20.498208, 20.927653, 21.366609, 21.827923, 22.297936, 22.802929, 23.325426, 23.872344, 24.428708, 25.016547, 25.616663, 26.249815, 26.888493, 27.563838, 28.246317, 28.944507, 29.626186, 30.32344, 31.005915, 31.691752, 32.3539, 33.030123, 33.692286, 34.350532, 34.984611, 35.626553, 36.250913, 36.878655, 37.489663, 38.12155, 38.748073, 39.384594, 40.00854, 40.654627, 41.292757, 41.937789, 42.578436], "PSL_0.15-17": [0.147178, 0.148512, 0.14984, 0.151149, 0.152463, 0.153736, 0.155037, 0.156353, 0.157733, 0.159147, 0.160631, 0.162104, 0.163632, 0.165116, 0.166619, 0.168103, 0.169663, 0.171215, 0.172809, 0.174372, 0.175972, 0.177499, 0.17899, 0.180473, 0.181989, 0.183515, 0.185125, 0.18674, 0.188361, 0.189958, 0.191562, 0.193131, 0.194757, 0.196404, 0.198108, 0.199817, 0.201587, 0.203405, 0.205329, 0.207304, 0.209425, 0.211626, 0.213932, 0.216303, 0.218782, 0.221367, 0.224093, 0.226903, 0.229915, 0.233032, 0.236228, 0.23945, 0.242773, 0.246132, 0.249607, 0.253107, 0.256744, 0.260442, 0.264187, 0.267911, 0.271706, 0.275499, 0.279403, 0.283227, 0.287138, 0.290997, 0.294872, 0.29859, 0.30237, 0.306117, 0.310001, 0.313851, 0.317863, 0.321889, 0.326007, 0.330069, 0.334253, 0.338447, 0.34288, 0.347352, 0.352069, 0.356884, 0.361907, 0.366927, 0.372137, 0.377479, 0.383123, 0.38886, 0.395014, 0.40144, 0.408224, 0.415169, 0.422523, 0.430111, 0.438266, 0.446544, 0.455456, 0.464683, 0.47431, 0.483937, 0.494039, 0.504239, 0.515062, 0.525963, 0.537475, 0.549211, 0.561363, 0.573305, 0.585638, 0.597968, 0.610797, 0.623491, 0.637091, 0.650905, 0.665095, 0.679159, 0.693809, 0.708272, 0.723433, 0.738634, 0.754816, 0.771442, 0.788866, 0.806406, 0.825041, 0.844056, 0.864269, 0.884896, 0.907133, 0.930247, 0.954702, 0.979641, 1.006303, 1.033916, 1.063887, 1.094818, 1.128497, 1.163781, 1.201442, 1.239666, 1.280344, 1.321963, 1.366094, 1.410407, 1.457152, 1.504424, 1.552681, 1.599797, 1.647969, 1.695302, 1.74325, 1.790112, 1.838436, 1.886361, 1.934874, 1.982394, 2.030952, 2.078624, 2.127138, 2.174776, 2.224535, 2.274453, 2.325111, 2.374953, 2.426211, 2.476709, 2.528855, 2.580825, 2.635387, 2.690558, 2.747551, 2.803991, 2.862899, 2.922291, 2.984056, 3.046042, 3.113385, 3.182289, 3.254006, 3.326432, 3.402919, 3.479686, 3.56089, 3.643269, 3.731866, 3.82319, 3.919206, 4.01622, 4.118729, 4.222422, 4.329813, 4.437176, 4.549892, 4.663274, 4.778641, 4.892855, 5.010383, 5.12713, 5.24763, 5.367036, 5.491243, 5.615306, 5.74164, 5.86515, 5.99241, 6.118721, 6.248725, 6.377145, 6.511253, 6.646127, 6.784049, 6.920263, 7.061721, 7.203762, 7.351069, 7.498659, 7.655424, 7.815799, 7.983194, 8.152294, 8.331328, 8.513941, 8.705466, 8.90023, 9.109121, 9.324911, 9.550495, 9.779767, 10.021903, 10.269101, 10.529969, 10.793235, 11.071817, 11.35364, 11.642367, 11.92479, 12.214337, 12.498558, 12.785157, 13.062966, 13.34801, 13.628646, 13.909346, 14.181604, 14.459354, 14.731797, 15.008272, 15.280104, 15.564339, 15.849489, 16.142262, 16.431695, 16.733284, 17.03231, 17.334961, 17.635557], "water_0.6-40": [0.475328874, 0.476797513, 0.478175666, 0.479502075, 0.480855492, 0.482239192, 0.483776821, 0.485514795, 0.487586124, 0.490033954, 0.493015369, 0.49644285, 0.500526891, 0.504620049, 0.508623279, 0.512432791, 0.516276412, 0.519917789, 0.523446881, 0.526657368, 0.529644951, 0.532170415, 0.534453013, 0.536612172, 0.538707124, 0.540707499, 0.542704885, 0.544602005, 0.546412089, 0.548115794, 0.54976444, 0.551336908, 0.552945782, 0.5545795, 0.556307547, 0.558111326, 0.560094002, 0.56230309, 0.564890776, 0.567889907, 0.571592672, 0.576088823, 0.581680177, 0.588617321, 0.601561496, 0.630479813, 0.676961544, 0.710966886, 0.735991613, 0.756999913, 0.775663514, 0.795802163, 0.817335328, 0.834507604, 0.851033998, 0.86681952, 0.883636475, 0.904097147, 0.945168374, 0.987512487, 1.00945989, 1.024622743, 1.037300638, 1.04742767, 1.055919888, 1.062703414, 1.067781829, 1.071556532, 1.074791681, 1.07782548, 1.081217504, 1.085261064, 1.090688654, 1.099784657, 1.101313854, 1.134070536, 1.209881892, 1.226633942, 1.276581131, 1.281214165, 1.299169605, 1.401316835, 1.41500474, 1.488659509, 1.499543839, 1.530187633, 1.612875286, 1.666529026, 1.676728327, 1.692803248, 1.697021378, 1.743202139, 1.774124289, 1.79524413, 1.845877084, 1.860421324, 2.020064767, 2.022618315, 2.088301883, 2.15270898, 2.166822976, 2.19656516, 2.196871589, 2.366985679, 2.567716135, 2.713412113, 3.023724973, 3.116313593, 3.258662351, 3.499997015, 3.560935854, 3.656816689, 3.701894939, 4.128937642, 4.246310184, 4.294054709, 4.442235484, 4.449948153, 4.653026664, 4.653982923, 4.67225491, 4.861758846, 5.128331636, 5.178882979, 5.3989097, 5.488764992, 5.697755771, 5.796959675, 5.849201526, 5.861379666, 6.181802879, 6.234781395, 6.270167934, 6.456362015, 6.664095866, 6.818273185, 7.045264319, 7.199039758, 7.744351806, 8.149762235, 8.389541055, 9.106277016, 9.376108012, 9.458106894, 9.720177509, 9.891769321, 9.893218147, 10.08342955, 11.13544922, 11.3674229, 11.97956261, 12.05205985, 12.13275325, 12.52580911, 12.65504996, 12.74203407, 13.5130931, 13.60890061, 14.00643198, 14.01971045, 14.62845349, 14.68718025, 15.08350885, 15.08634042, 15.26579923, 15.48530688, 15.78181646, 15.87183591, 15.88837124, 15.99151022, 16.21562139, 16.3392285, 17.09296412, 17.30950528, 17.49875152, 17.91853132, 18.81127331, 18.88275366, 19.49931861, 20.50310055, 20.67596729, 21.43256304, 21.66692463, 22.38056288, 22.41687813, 23.32114574, 23.59800118, 24.6884587, 26.15910161, 26.40985223, 26.54907612, 26.82122253, 27.95378788, 28.31828571, 28.62308926, 28.9859605, 31.70831679, 33.30483755, 33.31872983, 33.47237149, 33.83613691, 34.14117219, 34.29535607, 35.96238407, 36.45040779, 36.96988842, 39.31445632, 39.80082648, 39.97625745, 40.4735219, 41.12239047, 41.36883415, 41.44721931, 42.14962289, 43.5535701, 44.66132244, 45.18348652, 45.4997003, 45.62804903, 46.07948013, 47.22685994, 47.31823406, 48.04153067, 50.09042257, 51.10002286, 51.70165447, 54.88557633, 54.89575025, 56.84483279, 57.63884448, 59.89426308, 62.48060031, 65.02975953, 65.31940219, 66.72726474, 66.93637203, 68.96794765, 70.10028923, 73.92440633, 74.13015358, 74.791476, 78.61039438, 81.12774565, 81.78167273, 84.31901307, 87.67904454, 87.73430049, 88.07791102, 88.92650157, 89.09216846, 89.90121531, 90.14220699, 93.09415699, 94.34675245, 95.23367622, 99.56794522], "water_0.15-17": [0.19227805, 0.195682843, 0.198983343, 0.20211289, 0.205059225, 0.207724906, 0.210261443, 0.212640197, 0.214941426, 0.217106159, 0.219184031, 0.221069702, 0.222864072, 0.224475983, 0.226007321, 0.227451721, 0.228935989, 0.230420372, 0.232001183, 0.23365707, 0.235515886, 0.237498239, 0.2396823, 0.24214974, 0.245031001, 0.248355538, 0.252390654, 0.257053516, 0.262427305, 0.268474128, 0.275372623, 0.282991081, 0.29186836, 0.307406033, 0.399923672, 0.402950618, 0.406095451, 0.409547965, 0.413400206, 0.41751259, 0.422044242, 0.42680368, 0.431777327, 0.436801452, 0.441881131, 0.446916295, 0.451869098, 0.456536345, 0.461007333, 0.465043657, 0.468581314, 0.47159057, 0.474204957, 0.476473849, 0.478591721, 0.480677994, 0.48300681, 0.485758086, 0.489139191, 0.49325646, 0.498338142, 0.504028299, 0.509556422, 0.514585055, 0.519317611, 0.523556277, 0.527348524, 0.530511705, 0.533271375, 0.535775297, 0.538169182, 0.540358784, 0.542467011, 0.544426232, 0.546291497, 0.548017646, 0.549703069, 0.551325101, 0.552997124, 0.554673551, 0.55647017, 0.558378723, 0.56050201, 0.562815814, 0.565485426, 0.568582588, 0.572346583, 0.576807678, 0.58246436, 0.589712032, 0.604097302, 0.635149648, 0.681785255, 0.713426518, 0.737929379, 0.758135266, 0.777197248, 0.798828865, 0.820820152, 0.838396525, 0.855899917, 0.87246732, 0.89199909, 0.922871585, 0.974103329, 1.005591361, 1.023715678, 1.037668183, 1.049003877, 1.057952428, 1.064979646, 1.069897601, 1.073922024, 1.077493706, 1.081305379, 1.085788096, 1.091724556, 1.102779697, 1.143265693, 1.143675182, 1.163586446, 1.246663736, 1.281034981, 1.289349324, 1.374261238, 1.401296895, 1.415000046, 1.428202899, 1.456793, 1.496478358, 1.51027838, 1.547046871, 1.573966487, 1.607826932, 1.61288441, 1.673303193, 1.682765991, 1.700659399, 1.712959793, 1.752359685, 1.764561073, 1.963587787, 1.975472036, 2.018506015, 2.109050442, 2.137584399, 2.163430246, 2.198779576, 2.206574596, 2.521503927, 2.600807492, 2.930644138, 3.224767773, 3.26559294, 3.299391563, 3.468402268, 3.55387855, 4.015901324, 4.14533435, 4.15481853, 4.204793932, 4.306427442, 4.484413043, 4.509869078, 4.659718938, 5.012878336, 5.02631696, 5.094605209, 5.216818908, 5.421478915, 5.465600408, 5.466342553, 5.792080706, 5.800707245, 5.801478634, 5.896858039, 6.314835626, 6.344372707, 6.479563152, 6.717522876, 6.889473096, 7.196842924, 7.385283045, 7.599896247, 7.722296477, 7.896454473, 7.921113299, 8.543756839, 9.095455989, 9.16683766, 9.340296673, 9.527426832, 9.70141772, 11.10018093, 11.16424998, 11.373042, 12.25953607, 12.46820121, 12.59184634, 12.89654491, 12.91132697, 13.34641457, 13.9706481, 14.15548153, 14.28459638, 14.42672431, 14.59952971, 15.21856797, 15.50879655, 15.60034721, 15.92875268, 16.35351736, 16.37616054, 16.42409686, 16.83332527, 17.12982341, 17.31701994, 18.02256439, 18.16605357, 18.20476917, 18.49994924, 19.20076453, 19.39154934, 21.89001477, 21.99989778, 21.99993105, 23.30541595, 23.58030073, 23.99543799, 24.04375695, 25.18505013, 25.56282424, 26.15732199, 26.34740847, 26.4192903, 27.51664818, 27.78718441, 28.68872451, 30.81710534, 31.19347354, 32.34758429, 32.53704978, 33.36324834, 33.46006639, 33.50015573, 34.33790788, 34.94707083, 35.5539353, 35.59328655, 35.70406319, 35.98700435, 36.75952545, 37.4023428, 39.35282551, 39.88672896, 41.79105594]}
@@ -0,0 +1,17 @@
1
+ 0.38
2
+ 0.46
3
+ 0.66
4
+ 0.92
5
+ 1.20
6
+ 1.47
7
+ 1.83
8
+ 2.54
9
+ 3.50
10
+ 4.50
11
+ 5.75
12
+ 7.25
13
+ 9.00
14
+ 11.00
15
+ 13.00
16
+ 15.00
17
+ 16.75
@@ -0,0 +1,25 @@
1
+ 0.35
2
+ 0.46
3
+ 0.66
4
+ 1.00
5
+ 1.30
6
+ 1.70
7
+ 2.30
8
+ 3.00
9
+ 4.00
10
+ 5.20
11
+ 6.50
12
+ 8.00
13
+ 10.00
14
+ 12.00
15
+ 14.00
16
+ 16.00
17
+ 18.00
18
+ 20.00
19
+ 22.00
20
+ 25.00
21
+ 28.00
22
+ 31.00
23
+ 34.00
24
+ 37.00
25
+ 40.00
@@ -0,0 +1,17 @@
1
+ 1.195527059999999947e-01
2
+ 1.408946440000000133e-01
3
+ 1.690683370000000130e-01
4
+ 2.042269489999999910e-01
5
+ 2.275238950000000038e-01
6
+ 2.532918419999999893e-01
7
+ 2.792857189999999878e-01
8
+ 3.542688199999999843e-01
9
+ 6.041511750000000402e-01
10
+ 7.051028409999999802e-01
11
+ 7.858771890000000315e-01
12
+ 1.100686924999999983e+00
13
+ 1.117622254000000037e+00
14
+ 1.765832381999999923e+00
15
+ 2.690129739000000075e+00
16
+ 3.014558061999999872e+00
17
+ 4.392791391000000267e+00
@@ -0,0 +1,86 @@
1
+ import pandas as pd
2
+ import glob
3
+ import os
4
+ import re
5
+ from functools import reduce
6
+ import argparse
7
+
8
+
9
+ def merge_sensor_data(dir_in, dir_out):
10
+ dir_in = dir_in.replace("\\", "/") + "/"
11
+ dir_out = dir_out.replace("\\", "/") + "/"
12
+
13
+ sub_dir = [f.path for f in os.scandir(dir_in) if f.is_dir()]
14
+ file_types = [".csv", ".txt"]
15
+ for sub_dir_ in sub_dir:
16
+ file_path = []
17
+ for file_type in file_types:
18
+ file_path.extend([x for x in glob.glob(sub_dir_ + "/*" + file_type)])
19
+ file_name = [os.path.basename(x).rsplit(".", 1)[0] for x in file_path]
20
+ instrument_name = [re.sub(r"[\.\-_][0-9]+", "", x) for x in file_name]
21
+ file_summary = pd.DataFrame(
22
+ {
23
+ "file_path": file_path,
24
+ "file_name": file_name,
25
+ "instrument_name": instrument_name,
26
+ }
27
+ )
28
+ data = {}
29
+ for instrument, grp in file_summary.groupby("instrument_name"):
30
+ data[instrument] = pd.concat(
31
+ [
32
+ pd.read_csv(
33
+ x,
34
+ index_col=False,
35
+ sep=pd.read_csv(
36
+ x, sep=None, iterator=True, nrows=2
37
+ )._engine.data.dialect.delimiter,
38
+ )
39
+ for x in grp.file_path
40
+ ],
41
+ ignore_index=True,
42
+ )
43
+
44
+ for key, val in data.items():
45
+ data[key] = data[key].dropna(axis=0, how="all")
46
+ data[key].columns = data[key].columns.str.replace(" ", "")
47
+ if "datetime" in data[key].columns:
48
+ data[key]["datetime"] = pd.to_datetime(data[key]["datetime"])
49
+ else:
50
+ if "time" not in data[key].columns:
51
+ data[key]["datetime"] = pd.to_datetime(data[key]["date"])
52
+ data[key].drop(["date"], axis=1, inplace=True)
53
+ else:
54
+ data[key]["datetime"] = pd.to_datetime(
55
+ data[key]["date"] + " " + data[key]["time"]
56
+ )
57
+ data[key].drop(["date", "time"], axis=1, inplace=True)
58
+ data[key] = data[key].set_index("datetime").resample("1s").mean()
59
+ data[key] = data[key].reset_index()
60
+ data[key] = data[key].dropna()
61
+ data[key].columns = [
62
+ x + "_" + key if "datetime" not in x else x for x in data[key].columns
63
+ ]
64
+
65
+ data_merged = reduce(
66
+ lambda left, right: pd.merge(left, right, on=["datetime"], how="outer"),
67
+ data.values(),
68
+ )
69
+ data_merged = data_merged.set_index("datetime")
70
+ data_merged = data_merged.sort_index()
71
+ data_merged.reset_index(inplace=True)
72
+ data_merged.to_csv(
73
+ dir_out + sub_dir_.split("/")[-1] + "_merged.csv", index=False
74
+ )
75
+ print(f"{len(sub_dir)} folders merged")
76
+
77
+
78
+ if __name__ == "__main__":
79
+ parser = argparse.ArgumentParser(description="Description for arguments")
80
+ parser.add_argument("dir_in", help="Input directory", type=str)
81
+ parser.add_argument("dir_out", help="Output directory", type=str)
82
+ argument = parser.parse_args()
83
+
84
+ merge_sensor_data(argument.dir_in, argument.dir_out)
85
+
86
+ print("Finished merging files")
@@ -0,0 +1,30 @@
1
+ import pandas as pd
2
+ import glob
3
+ import os
4
+ import argparse
5
+
6
+
7
+ def merge_wind_data(dir_in, dir_out):
8
+ dir_in = dir_in.replace("\\", "/") + "/"
9
+ dir_out = dir_out.replace("\\", "/") + "/"
10
+ file_path_wind = [x for x in glob.glob(dir_in + "/*.csv")]
11
+ df = pd.DataFrame({})
12
+ for file in file_path_wind:
13
+ file_name = os.path.basename(file)
14
+ start_time = pd.to_datetime(file_name[-23:-4], format='%Y-%m-%d_%H-%M-%S')
15
+ df_ = pd.read_csv(file)
16
+ df_['datetime'] = start_time + pd.to_timedelta(df_['Flight time'])
17
+ df = pd.concat([df, df_], ignore_index=True)
18
+ df.to_csv(dir_out + "wind_merged.csv", index=False)
19
+ print(f"{len(file_path_wind)} files merged")
20
+
21
+
22
+ if __name__ == "__main__":
23
+ parser = argparse.ArgumentParser(description="Description for arguments")
24
+ parser.add_argument("dir_in", help="Input directory", type=str)
25
+ parser.add_argument("dir_out", help="Output directory", type=str)
26
+ argument = parser.parse_args()
27
+
28
+ merge_wind_data(argument.dir_in, argument.dir_out)
29
+
30
+ print("Finished merging files")
@@ -0,0 +1,62 @@
1
+ import numpy as np
2
+ import importlib.resources
3
+ import pandas as pd
4
+
5
+ n2_binedges = (
6
+ importlib.resources.files("UAVision.bin_edges")
7
+ .joinpath("opcN2_binedges.txt")
8
+ .read_text()
9
+ )
10
+ n2_binedges = np.fromstring(n2_binedges, sep="\n")
11
+
12
+ n3_binedges = (
13
+ importlib.resources.files("UAVision.bin_edges")
14
+ .joinpath("opcN3_binedges.txt")
15
+ .read_text()
16
+ )
17
+ n3_binedges = np.fromstring(n3_binedges, sep="\n")
18
+
19
+
20
+ def calculate_concentration(df, bin_label, flow_label=None, period_label=None):
21
+ """
22
+ Calculate dN/dLogDp from OPC N2 and N3
23
+ df: dataframe containing bin counts and flow rate
24
+ bin_label: list of bin column names (string)
25
+ flow_label: flow rate column name (string), only for OPC N3
26
+ period_label: sampling period column name (string), only for OPC N3
27
+ return: dN/dLogDp dataframe for OPC N2
28
+ concentration and dN/dLogDp dataframe for OPC N3
29
+ """
30
+ if len(bin_label) == 16:
31
+ print("OPC-N2")
32
+ dlog_bin = np.log10(n2_binedges[1:]) - np.log10(n2_binedges[:-1])
33
+ dndlogdp = df[bin_label].div(dlog_bin, axis=1)
34
+ return dndlogdp
35
+
36
+ elif len(bin_label) == 24:
37
+ print("OPC-N3")
38
+ dlog_bin = np.log10(n3_binedges[1:]) - np.log10(n3_binedges[:-1])
39
+ total_volume = df[flow_label] / 100
40
+ period = df[period_label] / 100
41
+ concentration = df[bin_label].div(total_volume, axis=0).div(period, axis=0)
42
+ dndlogdp = concentration.div(dlog_bin, axis=1)
43
+ return concentration, dndlogdp
44
+
45
+ def calculate_lag(df, var1, var2, lag):
46
+ """
47
+ Calculate the lag between two variables, same dataframe.
48
+ Please resample the dataframe so spacing is consistent
49
+ df: dataframe containing the two variables
50
+ var1: first variable column name (string)
51
+ var2: second variable column name (string)
52
+ lag: maximum lag to consider (int)
53
+ """
54
+ lag_range = np.arange(-lag, lag+1)
55
+ df_corr = pd.DataFrame({
56
+ 'covariance': np.array([df[var1].corr(df[var2].shift(x)) for x in lag_range]),
57
+ 'lag': lag_range})
58
+ df_corr['covariance'] = df_corr['covariance'].abs()
59
+ imax = df_corr['covariance'].idxmax()
60
+ lag_max = df_corr['lag'][imax]
61
+ print(f"Max correlation when shift forward {var2} by {lag_max} units")
62
+ return lag_max
@@ -0,0 +1,332 @@
1
+ import pandas as pd
2
+ import numpy as np
3
+ import json
4
+ import importlib.resources
5
+
6
+ mcda_midbin_all = (
7
+ importlib.resources.files("UAVision.bin_edges").joinpath("mcda_midbin_all.txt").read_text()
8
+ )
9
+ mcda_midbin_all = json.loads(mcda_midbin_all)
10
+
11
+ pops_binedges = (
12
+ importlib.resources.files("UAVision.bin_edges").joinpath("pops_binedges.txt").read_text()
13
+ )
14
+ pops_binedges = np.fromstring(pops_binedges, sep="\n")
15
+
16
+
17
+ def calculate_height(p0, p1, T0, T1):
18
+ """
19
+ Calculate height based on hydrostatic pressure equation, assuming a uniform layer
20
+
21
+ p0: pressure at lower level (hPa)
22
+ p1: pressure at upper level (hPa)
23
+ T0: temperature at lower level (K)
24
+ T1: temperature at upper level (K)
25
+ """
26
+ R = 287.05
27
+ g = 9.80665
28
+ height = R / g * ((T0 + T1) / 2 + 273.15) * np.log(p0 / p1)
29
+ return height
30
+
31
+
32
+ def calculate_height_df(df, p, T):
33
+ """
34
+ Advance calculation of height based on hydrostatic pressure equation,
35
+ assuming mini uniform layer
36
+ df: dataframe containing pressure and temperature columns
37
+ p: pressure column name (string)
38
+ T: temperature column name (string)
39
+ return: dataframe with height column added
40
+ """
41
+ df_height = df.copy()
42
+ df_height.dropna(subset=p, inplace=True)
43
+ height = np.zeros_like(df_height[p])
44
+ height[1:] = calculate_height(
45
+ df_height[p][:-1].values,
46
+ df_height[p][1:].values,
47
+ df_height[T][:-1].values,
48
+ df_height[T][1:].values,
49
+ )
50
+ df_height["height"] = height
51
+ df["height"] = df_height["height"]
52
+ df.replace({"height": np.nan}, 0, inplace=True)
53
+ df["height"] = df["height"].cumsum()
54
+ return df
55
+
56
+
57
+ def preprocess_bme(file):
58
+ """
59
+ BME processing
60
+ file: path to bme csv file (string)
61
+ return: processed dataframe
62
+ """
63
+ df = pd.read_csv(file)
64
+ df = df.dropna(axis=0)
65
+ df = df.reset_index(drop=True)
66
+ df["datetime"] = pd.to_datetime(df["date"] + " " + df["time"])
67
+ df = df.drop(["date", "time"], axis=1)
68
+ time_col = df.pop("datetime")
69
+ df.insert(0, "datetime", time_col)
70
+ df = df.rename(
71
+ {
72
+ "temp_bme": "temp_bme (C)",
73
+ "press_bme": "press_bme (hPa)",
74
+ "rh_bme": "rh_bme (%)",
75
+ },
76
+ axis=1,
77
+ )
78
+ return df
79
+
80
+
81
+ def preprocess_cpc(file):
82
+ """
83
+ CPC processing
84
+ file: path to cpc csv file (string)
85
+ return: processed dataframe
86
+ """
87
+ df = pd.read_csv(file)
88
+ df = df.dropna(axis=0)
89
+ df = df.reset_index(drop=True)
90
+ df["datetime"] = pd.to_datetime(df["date_time"])
91
+ df.replace(0, np.nan, inplace=True) # 0 values are invalid
92
+ df = df.drop(["date_time"], axis=1)
93
+ time_col = df.pop("datetime")
94
+ df.insert(0, "datetime", time_col)
95
+ df = df.rename(
96
+ {"N conc(1/ccm)": "N_conc_cpc (cm-3)", "Pressure (hPa)": "press_cpc (hPa)"},
97
+ axis=1,
98
+ )
99
+ return df
100
+
101
+
102
+ def preprocess_mcda(file, size):
103
+ """
104
+ mCDA processing, calculate derived parameters as well
105
+ file: path to mcda csv file (string)
106
+ size: size category, ['PSL_0.6-40', 'PSL_0.15-17', 'water_0.6-40', 'water_0.15-17']
107
+ return: processed dataframe
108
+ """
109
+ # calculate size dlog_bin
110
+ print(size)
111
+ mid_bin = np.array(mcda_midbin_all[size], dtype=float)
112
+ mid_bin = mid_bin[81:]
113
+ binedges = np.append(
114
+ np.append(
115
+ mid_bin[0] - (-mid_bin[0] + mid_bin[1]) / 2,
116
+ (mid_bin[:-1] + mid_bin[1:]) / 2,
117
+ ),
118
+ (mid_bin[-1] - mid_bin[-2]) / 2 + mid_bin[-1],
119
+ )
120
+ dlog_bin = np.log10(binedges[1:]) - np.log10(binedges[:-1])
121
+
122
+ # Load file
123
+ df = pd.read_csv(file, skiprows=1, header=None, dtype=str)
124
+ df = df.iloc[:, np.r_[[0], 82:257, -6:0]]
125
+ df = df.dropna(axis=0)
126
+ df = df.reset_index(drop=True)
127
+ df.columns = np.arange(df.columns.size)
128
+ df[0] = pd.to_datetime(df[0], format="%Y%m%d%H%M%S")
129
+
130
+ dndlog_label = ["bin" + str(x) + "_mcda (dN/dlogDp)" for x in range(1, 176)]
131
+ conc_label = ["bin" + str(x) + "_mcda (cm-3)" for x in range(1, 176)]
132
+ pm_label = [
133
+ "pcount_mcda",
134
+ "pm1_mcda",
135
+ "pm25_mcda",
136
+ "pm4_mcda",
137
+ "pm10_mcda",
138
+ "pmtot_mcda",
139
+ ]
140
+ df.columns = np.r_[["datetime"], conc_label, pm_label]
141
+
142
+ # Convert hex to int
143
+ df[conc_label] = df[conc_label].map(
144
+ lambda x: int(x, base=16)
145
+ )
146
+ # Convert to float
147
+ df = df.set_index("datetime").astype("float").reset_index()
148
+ # Bin counts
149
+ df_bins = df[conc_label].copy().to_numpy().astype(float)
150
+ # Calculate concentration cm-3
151
+ df[conc_label] = df[conc_label] / 10 / 46.67 # 10s averaged, 2.8L/min flow = 46.67 ccm/s
152
+
153
+ # Calculate dN/dlogDp
154
+ dndlog = df[conc_label] / dlog_bin
155
+ dndlog.columns = dndlog_label
156
+ df = pd.concat([df, dndlog], axis=1)
157
+ # Calculate CDNC
158
+ df["Nd_mcda (cm-3)"] = df_bins.sum(axis=1) / 10 / 46.67
159
+ # Calculate LWC
160
+ conc_perbin = df_bins / 10 / (2.8e-3 / 60)
161
+ lwc_perbin = conc_perbin * 1e6 * np.pi / 6 * (mid_bin * 1e-6) ** 3
162
+ lwc_sum = lwc_perbin.sum(axis=1)
163
+ df["LWC_mcda (g/m3)"] = lwc_sum
164
+ # Calculate MVD
165
+ p_lwc_perbin = np.divide(
166
+ lwc_perbin,
167
+ lwc_sum[:, np.newaxis],
168
+ out=np.zeros_like(lwc_perbin),
169
+ where=lwc_sum[:, np.newaxis] != 0,
170
+ )
171
+ cumsum_lwc_perbin = p_lwc_perbin.cumsum(axis=1)
172
+ cumsum_lwc_perbin[df_bins == 0] = np.nan
173
+ # find imin and imax, they contain the point where cumsum_lwc_perbin == 0.5
174
+ imax = np.argmax((cumsum_lwc_perbin > 0.5), axis=1)
175
+ imin = (
176
+ cumsum_lwc_perbin.shape[1]
177
+ - np.argmax(cumsum_lwc_perbin[:, ::-1] < 0.5, axis=1)
178
+ - 1
179
+ )
180
+ # The MVD formula is based on this where max is first non-zero bin cumsum > 0.5 and
181
+ # min is last non-zero bin cumsum < 0.5
182
+ # (0.5 - cum_min) / (cum_max - cum_min) = (bx - bmin) / (bmax - bmin)
183
+ cum_min = cumsum_lwc_perbin[np.arange(len(cumsum_lwc_perbin)), imin]
184
+ cum_max = cumsum_lwc_perbin[np.arange(len(cumsum_lwc_perbin)), imax]
185
+ bmin = mid_bin[imin]
186
+ bmax = mid_bin[imax]
187
+ df["MVD_mcda (um)"] = bmin + (0.5 - cum_min) / (cum_max - cum_min) * (bmax - bmin)
188
+ # Calculate ED
189
+ top = (conc_perbin * mid_bin**3).sum(axis=1)
190
+ bottom = (conc_perbin * mid_bin**2).sum(axis=1)
191
+ df["ED_mcda (um)"] = np.divide(
192
+ top, bottom, out=np.zeros_like(top), where=bottom != 0
193
+ )
194
+ # Drop columns
195
+ df = df.drop(["pcount_mcda", "pm4_mcda", "pmtot_mcda"], axis=1)
196
+ return df
197
+
198
+
199
+ def preprocess_pops(file):
200
+ """
201
+ POPS processing
202
+ file: path to pops csv file (string)
203
+ return: processed dataframe
204
+ """
205
+ df = pd.read_csv(file)
206
+ df = df.dropna(axis=0)
207
+ df = df.reset_index(drop=True)
208
+ df["datetime"] = pd.to_datetime(df["DateTime"], unit="s") + pd.Timedelta("2hour")
209
+ df = df.set_index("datetime").resample("1s").mean().dropna().reset_index()
210
+ df = df.drop(["DateTime"], axis=1)
211
+ time_col = df.pop("datetime")
212
+ df.insert(0, "datetime", time_col)
213
+
214
+ dlog_bin = np.log10(pops_binedges[1:]) - np.log10(pops_binedges[:-1])
215
+ pops_binlab = [
216
+ "b0",
217
+ "b1",
218
+ "b2",
219
+ "b3",
220
+ "b4",
221
+ "b5",
222
+ "b6",
223
+ "b7",
224
+ "b8",
225
+ "b9",
226
+ "b10",
227
+ "b11",
228
+ "b12",
229
+ "b13",
230
+ "b14",
231
+ "b15",
232
+ ]
233
+ # df.columns = [
234
+ # "bin" + str(int(x[1:]) + 1) + "_pops (cm-3)"
235
+ # if re.search("b[0-9]+", x)
236
+ # else x
237
+ # for x in df.columns
238
+ # ]
239
+ dndlog_label = ["bin" + str(x) + "_pops (dN/dlogDp)" for x in range(1, 17)]
240
+ conc_label = ["bin" + str(x) + "_pops (cm-3)" for x in range(1, 17)]
241
+ df = df.rename(columns={x:y for x,y in zip(pops_binlab, conc_label)})
242
+ # Calculate concentration cm-3
243
+ df[conc_label] = df[conc_label].div(df[" POPS_Flow"] * 16.6667, axis=0)
244
+ # Calculate dN/dlogDp
245
+ dndlog = df[conc_label].div(dlog_bin, axis=1)
246
+ dndlog.columns = dndlog_label
247
+ df = pd.concat([df, dndlog], axis=1)
248
+
249
+ df = df.drop(
250
+ [
251
+ " Status",
252
+ " PartCt",
253
+ " BL",
254
+ " BLTH",
255
+ " STD",
256
+ " TofP",
257
+ " PumpFB",
258
+ " LDTemp",
259
+ " LaserFB",
260
+ " LD_Mon",
261
+ " Temp",
262
+ " BatV",
263
+ " Laser_Current",
264
+ " Flow_Set",
265
+ "PumpLife_hrs",
266
+ " BL_Start",
267
+ " TH_Mult",
268
+ " nbins",
269
+ " logmin",
270
+ " logmax",
271
+ " Skip_Save",
272
+ " MinPeakPts",
273
+ "MaxPeakPts",
274
+ " RawPts",
275
+ ],
276
+ axis=1,
277
+ )
278
+ df = df.rename(
279
+ {
280
+ " PartCon": "N_conc_pops (cm-3)",
281
+ " P": "press_pops (hPa)",
282
+ " POPS_Flow": "flow_rate_pops (l/m)",
283
+ },
284
+ axis=1,
285
+ )
286
+ return df
287
+
288
+
289
+ def calculate_binedges(midbin):
290
+ """
291
+ calculate bin edges from mid bin
292
+ midbin: mid bin array
293
+ return: binedges array
294
+ """
295
+ binedges = np.append(
296
+ np.append(
297
+ midbin[0] - (-midbin[0] + midbin[1]) / 2, (midbin[:-1] + midbin[1:]) / 2
298
+ ),
299
+ (midbin[-1] - midbin[-2]) / 2 + midbin[-1],
300
+ )
301
+ return binedges
302
+
303
+
304
+ def calculate_midbin(pops_binedges):
305
+ """
306
+ calculate midbin from bin edges
307
+ pops_binedges: binedges array
308
+ return: midbin array
309
+ """
310
+ # pops_binedges = np.loadtxt('pops_binedges.txt')
311
+ pops_midbin = (pops_binedges[1:] + pops_binedges[:-1]) / 2
312
+ return pops_midbin
313
+
314
+
315
+ def cloudmask(df):
316
+ import re
317
+ """cloud mask for mcda"""
318
+ if df["datetime"][0] < pd.Timestamp("20221003"):
319
+ size = "water_0.15-17"
320
+ else:
321
+ size = "water_0.6-40"
322
+ cda_midbin = np.array(mcda_midbin_all[size], dtype=float)
323
+ cda_midbin = cda_midbin[81:]
324
+ # RH > 80%
325
+ rh_cloud = df["rh_bme (%)"] > 80
326
+ # Count > 1 in 10s with size > 2 um
327
+ bin_lab = [x for x in df.columns if re.search(r"bin[0-9]+_mcda \(cm-3\)", x)]
328
+ bin_lab_cloud = bin_lab[np.argmax(cda_midbin > 2) :]
329
+ bin_count = df[bin_lab]
330
+ count_cloud = bin_count[bin_lab_cloud].sum(axis=1) * 10 > 5
331
+ cloudmask = rh_cloud & count_cloud
332
+ return cloudmask
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: UAVision
3
+ Version: 1.0.0
4
+ Summary: UAV instrument data processing
5
+ Author-email: VIET LE <viet.le@fmi.fi>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2019-2025 Finnish Meteorological Institute
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Requires-Python: >=3.11
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy
31
+ Requires-Dist: matplotlib
32
+ Requires-Dist: pandas
33
+ Dynamic: license-file
34
+
35
+ # UAVision
36
+ UAVision is a Python package for UAV instrument data processing (particle counters, BME sensors, POPS, mCDA, OPC).
37
+ It provides preprocessing utilities, concentration calculations.
38
+
39
+ ## Features
40
+ - Preprocessing and derived metrics for MCDA, POPS and other instruments.
41
+ - OPC / Mavic helpers for concentration and lag calculations.
42
+ - Included bin-edge resources for common instruments (mcda, pops, opc).
43
+ - For mcda, there are 4 options for sizes: ['PSL_0.6-40', 'PSL_0.15-17', 'water_0.6-40', 'water_0.15-17']
44
+
45
+ ## Key modules (examples)
46
+ - UAVision.preprocess — functions like preprocess_mcda, preprocess_pops, calculate_height_df.
47
+ - UAVision.mavic.preprocess — functions like calculate_concentration, calculate_lag.
48
+ - Package data: /bin_edges/*.txt
49
+
50
+ ## Example usage
51
+ ```sh
52
+ from UAVision.preprocess import preprocess_mcda
53
+ df = preprocess_mcda("data_path/datafile.csv", size="water_0.15-17")
54
+ ```
55
+ # Notes
56
+ Bin-edge files are included as package data and can be loaded with importlib.resources. See pyproject.toml for packaging metadata.
57
+
58
+ # Contributing / Contact
59
+ Author: viet.le@fmi.fi — pull requests and bug reports welcome.
@@ -0,0 +1,22 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ src/UAVision.egg-info/PKG-INFO
6
+ src/UAVision.egg-info/SOURCES.txt
7
+ src/UAVision.egg-info/dependency_links.txt
8
+ src/UAVision.egg-info/requires.txt
9
+ src/UAVision.egg-info/top_level.txt
10
+ src/UAVision/preprocess.py
11
+ src/UAVision.egg-info/PKG-INFO
12
+ src/UAVision.egg-info/SOURCES.txt
13
+ src/UAVision.egg-info/dependency_links.txt
14
+ src/UAVision.egg-info/requires.txt
15
+ src/UAVision.egg-info/top_level.txt
16
+ src/UAVision/bin_edges/mcda_midbin_all.txt
17
+ src/UAVision/bin_edges/opcN2_binedges.txt
18
+ src/UAVision/bin_edges/opcN3_binedges.txt
19
+ src/UAVision/bin_edges/pops_binedges.txt
20
+ src/UAVision/mavic/merge_sensor_data.py
21
+ src/UAVision/mavic/merge_wind_data.py
22
+ src/UAVision/mavic/preprocess.py
@@ -0,0 +1,3 @@
1
+ numpy
2
+ matplotlib
3
+ pandas
@@ -0,0 +1 @@
1
+ UAVision