flightdata 0.2.11__tar.gz → 0.2.12__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.
Files changed (84) hide show
  1. {flightdata-0.2.11/flightdata.egg-info → flightdata-0.2.12}/PKG-INFO +1 -1
  2. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/base/table.py +37 -34
  3. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/scripts/collect_logs.py +4 -1
  4. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/scripts/flightline.py +4 -1
  5. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/state.py +1 -1
  6. {flightdata-0.2.11 → flightdata-0.2.12/flightdata.egg-info}/PKG-INFO +1 -1
  7. {flightdata-0.2.11 → flightdata-0.2.12}/test/base/test_table.py +16 -13
  8. {flightdata-0.2.11 → flightdata-0.2.12}/.github/workflows/publish_pypi.yml +0 -0
  9. {flightdata-0.2.11 → flightdata-0.2.12}/.gitignore +0 -0
  10. {flightdata-0.2.11 → flightdata-0.2.12}/.vscode/launch.json +0 -0
  11. {flightdata-0.2.11 → flightdata-0.2.12}/.vscode/settings.json +0 -0
  12. {flightdata-0.2.11 → flightdata-0.2.12}/LICENSE +0 -0
  13. {flightdata-0.2.11 → flightdata-0.2.12}/README.md +0 -0
  14. {flightdata-0.2.11 → flightdata-0.2.12}/examples/__init__.py +0 -0
  15. {flightdata-0.2.11 → flightdata-0.2.12}/examples/axis_rates.ipynb +0 -0
  16. {flightdata-0.2.11 → flightdata-0.2.12}/examples/data/__init__.py +0 -0
  17. {flightdata-0.2.11 → flightdata-0.2.12}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
  18. {flightdata-0.2.11 → flightdata-0.2.12}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
  19. {flightdata-0.2.11 → flightdata-0.2.12}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
  20. {flightdata-0.2.11 → flightdata-0.2.12}/examples/flight_data.py +0 -0
  21. {flightdata-0.2.11 → flightdata-0.2.12}/examples/flight_dynamics/00000150.json +0 -0
  22. {flightdata-0.2.11 → flightdata-0.2.12}/examples/flight_dynamics/__init__.py +0 -0
  23. {flightdata-0.2.11 → flightdata-0.2.12}/examples/flight_dynamics/box.f3a +0 -0
  24. {flightdata-0.2.11 → flightdata-0.2.12}/examples/flight_dynamics/param_id.py +0 -0
  25. {flightdata-0.2.11 → flightdata-0.2.12}/examples/state_analysis/__init__.py +0 -0
  26. {flightdata-0.2.11 → flightdata-0.2.12}/examples/state_analysis/axes.py +0 -0
  27. {flightdata-0.2.11 → flightdata-0.2.12}/examples/state_analysis/state_fill_plot.py +0 -0
  28. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/__init__.py +0 -0
  29. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/base/__init__.py +0 -0
  30. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/base/collection.py +0 -0
  31. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/base/constructs.py +0 -0
  32. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/base/labeling.py +0 -0
  33. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/base/numpy_encoder.py +0 -0
  34. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/coefficients.py +0 -0
  35. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/environment/__init__.py +0 -0
  36. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/environment/environment.py +0 -0
  37. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/environment/wind.py +0 -0
  38. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/flight/__init__.py +0 -0
  39. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/flight/ardupilot.py +0 -0
  40. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/flight/fields.py +0 -0
  41. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/flight/flight.py +0 -0
  42. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/flight/parameters.py +0 -0
  43. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/flow.py +0 -0
  44. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/model/__init__.py +0 -0
  45. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/model/aerodynamic.py +0 -0
  46. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/model/thrust.py +0 -0
  47. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata/origin.py +0 -0
  48. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata.egg-info/SOURCES.txt +0 -0
  49. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata.egg-info/dependency_links.txt +0 -0
  50. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata.egg-info/entry_points.txt +0 -0
  51. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata.egg-info/requires.txt +0 -0
  52. {flightdata-0.2.11 → flightdata-0.2.12}/flightdata.egg-info/top_level.txt +0 -0
  53. {flightdata-0.2.11 → flightdata-0.2.12}/pyproject.toml +0 -0
  54. {flightdata-0.2.11 → flightdata-0.2.12}/requirements-dev.txt +0 -0
  55. {flightdata-0.2.11 → flightdata-0.2.12}/requirements.txt +0 -0
  56. {flightdata-0.2.11 → flightdata-0.2.12}/setup.cfg +0 -0
  57. {flightdata-0.2.11 → flightdata-0.2.12}/test/EmailedBox.f3a +0 -0
  58. {flightdata-0.2.11 → flightdata-0.2.12}/test/__init__.py +0 -0
  59. {flightdata-0.2.11 → flightdata-0.2.12}/test/base/__init__.py +0 -0
  60. {flightdata-0.2.11 → flightdata-0.2.12}/test/base/test_base_constructs.py +0 -0
  61. {flightdata-0.2.11 → flightdata-0.2.12}/test/conftest.py +0 -0
  62. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/make_inputs.py +0 -0
  63. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/manual_F3A_P23.json +0 -0
  64. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/p23.BIN +0 -0
  65. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/p23.json +0 -0
  66. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/p23_box.f3a +0 -0
  67. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/p23_fc.json +0 -0
  68. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/p23_flight.json +0 -0
  69. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/vtol_hover.bin +0 -0
  70. {flightdata-0.2.11 → flightdata-0.2.12}/test/data/vtol_hover.json +0 -0
  71. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_environment/__init__.py +0 -0
  72. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_environment/test_environment.py +0 -0
  73. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_environment/test_environment_wind.py +0 -0
  74. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_fields.py +0 -0
  75. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_flight.py +0 -0
  76. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_model/__init__.py +0 -0
  77. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_model/test_model_coefficients.py +0 -0
  78. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_model/test_model_flow.py +0 -0
  79. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_origin.py +0 -0
  80. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_state/__init__.py +0 -0
  81. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_state/test_state.py +0 -0
  82. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_state/test_state_builders.py +0 -0
  83. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_state/test_state_conversions.py +0 -0
  84. {flightdata-0.2.11 → flightdata-0.2.12}/test/test_state/test_state_measurements.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flightdata
3
- Version: 0.2.11
3
+ Version: 0.2.12
4
4
  Summary: Module for handling UAV flight log data
5
5
  Author-email: Thomas David <thomasdavid0@gmail.com>
6
6
  License: GNU GPL v3
@@ -80,40 +80,16 @@ class Table:
80
80
  else:
81
81
  raise TypeError(f"Expected Number or slice, got {sli.__class__.__name__}")
82
82
 
83
-
84
83
  def slice_raw_t(self, sli):
85
84
  inds = self.data.reset_index(names="t2").set_index("t").loc[sli].t2.to_numpy()#set_index("t", drop=False).columns
86
85
 
87
86
  return self.__class__(self.data.loc[inds])
88
87
 
89
- @classmethod
90
- def stack(Cls, sections: list, overlap: int=1) -> Self:
91
- """Stack a list of Tables on top of each other.
92
- The overlap is the number of rows to overlap between each section
93
- """
94
- # first build list of index offsets, to be added to each dataframe
95
- if overlap > 0:
96
- offsets = np.cumsum([0] + [sec.data.index[-overlap] for sec in sections[:-1]])
97
- dfs = [section.data.iloc[:-overlap] for section in sections[:-1]] + [sections[-1].data]
98
- elif overlap == 0:
99
- offsets = np.cumsum([0] + [sec.duration + sec.dt[-1] for sec in sections[:-1]])
100
- dfs = [section.data for section in sections]
101
- else:
102
- raise AttributeError("Overlap must be >= 0")
103
-
104
- for df, offset in zip(dfs, offsets):
105
- df.index = np.array(df.index) - df.index[0] + offset
106
- combo = pd.concat(dfs)
107
- combo.index.name = "t"
108
-
109
- combo["t"] = combo.index
110
-
111
- return Cls(combo)
112
-
113
88
  def __iter__(self):
114
89
  for ind in list(self.data.index):
115
90
  yield self[ind]
116
91
 
92
+
117
93
  @classmethod
118
94
  def from_constructs(cls, *args,**kwargs) -> Self:
119
95
  kwargs = dict(
@@ -132,7 +108,7 @@ class Table:
132
108
  )
133
109
 
134
110
  return cls(df)
135
-
111
+
136
112
  def __repr__(self):
137
113
  return f"{self.__class__.__name__} Table(duration = {self.duration})"
138
114
 
@@ -160,6 +136,30 @@ class Table:
160
136
  ignore_index=True
161
137
  ).set_index("t", drop=False))
162
138
 
139
+ @classmethod
140
+ def stack(Cls, sections: list, overlap: int=1) -> Self:
141
+ """Stack a list of Tables on top of each other.
142
+ The overlap is the number of rows to overlap between each section
143
+ """
144
+ # first build list of index offsets, to be added to each dataframe
145
+ if overlap > 0:
146
+ offsets = np.cumsum([0] + [sec.data.index[-overlap] for sec in sections[:-1]])
147
+ dfs = [section.data.iloc[:-overlap] for section in sections[:-1]] + [sections[-1].data]
148
+ elif overlap == 0:
149
+ offsets = np.cumsum([0] + [sec.duration + sec.dt[-1] for sec in sections[:-1]])
150
+ dfs = [section.data for section in sections]
151
+ else:
152
+ raise AttributeError("Overlap must be >= 0")
153
+
154
+ for df, offset in zip(dfs, offsets):
155
+ df.index = np.array(df.index) - df.index[0] + offset
156
+ combo = pd.concat(dfs)
157
+ combo.index.name = "t"
158
+
159
+ combo["t"] = combo.index
160
+
161
+ return Cls(combo)
162
+
163
163
  def label(self, **kwargs) -> Self:
164
164
  return self.__class__(self.data.assign(**kwargs))
165
165
 
@@ -176,9 +176,11 @@ class Table:
176
176
 
177
177
  def get_subset_df(self, **kwargs) -> pd.DataFrame:
178
178
  dfo = self.data
179
+ sel = np.full(len(self.data), True)
179
180
  for k, v in kwargs.items():
180
- dfo = dfo.loc[dfo[k] == v, :]
181
- return dfo
181
+ sel = sel & (dfo[k] == v)
182
+
183
+ return self.data.loc[sel + (sel.astype(int).diff() == -1)]
182
184
 
183
185
  def get_label_subset(self, min_len=1, **kwargs) -> Self:
184
186
  return self.__class__(self.get_subset_df(**kwargs), min_len=min_len)
@@ -243,13 +245,14 @@ class Table:
243
245
  return self.label(**labels.to_dict(orient='list'))
244
246
 
245
247
  @classmethod
246
- def shift_multi(Cls, steps: int, tb1: Self, tb2: Self, min_len=2) -> Tuple[Self, Self]:
248
+ def shift_multi(Cls, steps: int, tb1: Self, tb2: Self, min_len=1) -> Tuple[Self, Self]:
247
249
  '''Take datapoints off the start of tb2 and add to the end tb1'''
248
- if (steps>0 and len(tb2)-min_len<steps) or (steps<0 and min_len - len(tb1) > steps):
249
- raise ValueError(f'Cannot Squash a Table to less than {min_len} datapoints')
250
- dfj = Cls.stack([tb1, tb2], overlap=0).data
251
- return Cls(dfj.iloc[:len(tb1)+steps, :]), \
252
- Cls(dfj.iloc[len(tb1)+steps:, :])
250
+ #if (steps>0 and len(tb2)-min_len<steps) or (steps<0 and min_len - len(tb1) > steps):
251
+ # raise ValueError(f'Cannot Squash a Table to less than {min_len} datapoints')
252
+ tj = Cls.stack([tb1, tb2]).shift_label(steps, min_len, **dict(tb1.labels.iloc[0]))
253
+
254
+ return Cls(tj.get_subset_df(**dict(tb1.labels.iloc[0]))), \
255
+ Cls(tj.get_subset_df(**dict(tb2.labels.iloc[0])))
253
256
 
254
257
  def shift_label_ratio(self, ratio: float, min_len=None, **kwargs) -> Self:
255
258
  '''shift a label within its allowable bounds, with a ratio of
@@ -25,4 +25,7 @@ def main():
25
25
  if not (folder / file.name).exists():
26
26
  print(f'copying {file} to {folder / file.name}')
27
27
  shutil.copyfile(file, folder / file.name )
28
-
28
+
29
+
30
+ if __name__ == '__main__':
31
+ main()
@@ -54,4 +54,7 @@ def main():
54
54
  else:
55
55
  box = box_from_log(Flight.from_log(plog), args.input)
56
56
 
57
- box.to_f3a_zone(Path(args.logdir) / f'box_{plog.stem}.f3a')
57
+ box.to_f3a_zone(Path(args.logdir) / f'box_{plog.stem}.f3a')
58
+
59
+ if __name__ == '__main__':
60
+ main()
@@ -217,7 +217,7 @@ class State(Table):
217
217
 
218
218
  def get_meid(self: State, manid: int, elid: int=None):
219
219
  st = self.get_manoeuvre(manid)
220
- if not elid is None:
220
+ if elid is not None:
221
221
  return st.get_element(elid)
222
222
  else:
223
223
  return st
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flightdata
3
- Version: 0.2.11
3
+ Version: 0.2.12
4
4
  Summary: Module for handling UAV flight log data
5
5
  Author-email: Thomas David <thomasdavid0@gmail.com>
6
6
  License: GNU GPL v3
@@ -8,7 +8,7 @@ from pytest import fixture
8
8
 
9
9
  @fixture
10
10
  def df():
11
- df = pd.DataFrame(np.linspace(0,100, 100), columns=['t'])
11
+ df = pd.DataFrame(np.linspace(0,5, 6), columns=['t'])
12
12
  return df.set_index("t", drop=False)
13
13
 
14
14
  @fixture
@@ -54,12 +54,15 @@ def test_get_subset_df(tab_full, labst):
54
54
  assert len(tab_full) == len(df)
55
55
 
56
56
 
57
- def test_shift_labels_ratios(tab_full):
58
- tf = tab_full.label(element='e0', manoeuvre='m0')
59
- tf.data.loc[tf.duration/2:,'element'] = 'e1'
60
-
57
+ def test_shift_labels_ratios(tab_full: Table):
58
+ tf: Table = Table.stack([
59
+ tab_full.label(element='e0', manoeuvre='m0'),
60
+ tab_full.label(element='e1', manoeuvre='m0')
61
+
62
+ ])
63
+
61
64
  assert sum(tf.shift_labels_ratios([0.5],2).element == 'e1') < sum(tf.element == 'e1')
62
- tf
65
+
63
66
 
64
67
  def test_stack(tab_full):
65
68
  tfn = Table.stack([tab_full.label(element='e0'), tab_full.label(element='e1')], overlap=0)
@@ -72,18 +75,18 @@ def test_stack(tab_full):
72
75
 
73
76
 
74
77
  def test_shift_multi(tab_full):
75
- t1, t2 = tab_full.label(element='e1'), tab_full.label(element='e2')
76
- tb1, tb2 = Table.shift_multi(2, t1, t2)
78
+ tabs = Table.stack([tab_full.label(element='e0'), tab_full.label(element='e1')], overlap=1).split_labels()
79
+ tb1, tb2 = Table.shift_multi(2, tabs['e0'], tabs['e1'])
77
80
 
78
81
  assert len(tb1) == len(tab_full) + 2
79
82
  assert len(tb2) == len(tab_full) - 2
80
83
  assert tb2.duration == tab_full.data.index[-3]
81
84
 
82
- tb1, tb2 = Table.shift_multi(-5, t1, t2)
85
+ tb1, tb2 = Table.shift_multi(-3, tabs['e0'], tabs['e1'])
83
86
 
84
- assert len(tb1) == len(tab_full) - 5
85
- assert len(tb2) == len(tab_full) + 5
86
- assert tb1.duration == tab_full.data.index[-6]
87
+ assert len(tb1) == len(tab_full) - 3
88
+ assert len(tb2) == len(tab_full) + 3
89
+ assert tb1.duration == tab_full.data.index[-4]
87
90
 
88
91
 
89
92
  def test_table_cumulative_labels(tab_full):
@@ -102,6 +105,6 @@ def test_table_cumulative_labels(tab_full):
102
105
  indexes = np.unique(res, return_index=True)[1]
103
106
  np.testing.assert_array_equal(
104
107
  [res[index] for index in sorted(indexes)],
105
- np.array(['a1_b1', 'a2_b1', 'a2_b2', 'a1_b1_1'])
108
+ np.array(['a1_b1_0', 'a2_b1_0', 'a2_b2_0', 'a1_b1_1'])
106
109
  )
107
110
  pass
File without changes
File without changes
File without changes
File without changes
File without changes