flightanalysis 0.2.12__tar.gz → 0.2.14__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 (147) hide show
  1. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/PKG-INFO +3 -3
  2. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/f3a_criteria_maker.py +29 -12
  3. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/analysis/el_analysis.py +2 -2
  4. flightanalysis-0.2.14/flightanalysis/analysis/manoeuvre_analysis/__init__.py +14 -0
  5. flightanalysis-0.2.14/flightanalysis/analysis/manoeuvre_analysis/alignment.py +97 -0
  6. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/analysis/manoeuvre_analysis/analysis.py +8 -8
  7. flightanalysis-0.2.14/flightanalysis/analysis/manoeuvre_analysis/basic.py +131 -0
  8. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/analysis/manoeuvre_analysis/complete.py +9 -12
  9. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/analysis/manoeuvre_analysis/scored.py +21 -3
  10. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/analysis/sch_analysis.py +3 -5
  11. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/IMAC_Unlimited2024_schedule.json +209 -209
  12. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/f3a_a25_schedule.json +166 -166
  13. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/f3a_f25_schedule.json +276 -276
  14. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/f3a_p23_schedule.json +304 -279
  15. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/f3a_p25_schedule.json +278 -278
  16. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/f3auk_clubman_schedule.json +118 -118
  17. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/f3auk_inter_schedule.json +111 -111
  18. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/__init__.py +1 -1
  19. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/builders/elbuilders.py +2 -15
  20. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/collectors.py +6 -2
  21. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/mandef.py +3 -0
  22. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/manparm.py +8 -9
  23. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/operations/operation.py +9 -1
  24. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/scheddef.py +2 -2
  25. flightanalysis-0.2.14/flightanalysis/definition/scheduleinfo.py +72 -0
  26. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/element.py +6 -6
  27. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/exponential.py +8 -6
  28. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/f3a_criteria.py +13 -13
  29. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/inter/combination.py +1 -1
  30. flightanalysis-0.2.14/flightanalysis/scoring/criteria/inter/comparison.py +20 -0
  31. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/intra/bounded.py +3 -3
  32. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/intra/continuous.py +3 -3
  33. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/intra/single.py +4 -5
  34. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/downgrade.py +7 -12
  35. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/measurement.py +19 -10
  36. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/results.py +16 -15
  37. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scripts/collect_scores.py +3 -3
  38. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis.egg-info/PKG-INFO +3 -3
  39. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis.egg-info/SOURCES.txt +2 -4
  40. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis.egg-info/requires.txt +2 -2
  41. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/requirements-dev.txt +1 -1
  42. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/requirements.txt +1 -1
  43. flightanalysis-0.2.12/examples/scoring/temp.py +0 -24
  44. flightanalysis-0.2.12/flightanalysis/analysis/manoeuvre_analysis/__init__.py +0 -8
  45. flightanalysis-0.2.12/flightanalysis/analysis/manoeuvre_analysis/alignment.py +0 -81
  46. flightanalysis-0.2.12/flightanalysis/analysis/manoeuvre_analysis/basic.py +0 -86
  47. flightanalysis-0.2.12/flightanalysis/definition/scheduleinfo.py +0 -45
  48. flightanalysis-0.2.12/flightanalysis/scoring/criteria/inter/comparison.py +0 -18
  49. flightanalysis-0.2.12/tests/test_schedule/test_element/test_split_optimiser.py +0 -15
  50. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/.github/workflows/publish_pypi.yml +0 -0
  51. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/.gitignore +0 -0
  52. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/LICENSE +0 -0
  53. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/MANIFEST.in +0 -0
  54. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/README.md +0 -0
  55. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/__init__.py +0 -0
  56. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/data/__init__.py +0 -0
  57. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
  58. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
  59. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
  60. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/__init__.py +0 -0
  61. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/judging.py +0 -0
  62. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/manoeuvres/__init__.py +0 -0
  63. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/manoeuvres/inter_analysis.py +0 -0
  64. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/manoeuvres/intra_analysis.py +0 -0
  65. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/manoeuvres/mans/__init__.py +0 -0
  66. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/manoeuvres/mans/extract_mans.py +0 -0
  67. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/manoeuvres/mans/tHat.json +0 -0
  68. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/examples/scoring/manoeuvres/positioning_analysis.py +0 -0
  69. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/__init__.py +0 -0
  70. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/analysis/__init__.py +0 -0
  71. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/data/__init__.py +0 -0
  72. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/builders/__init__.py +0 -0
  73. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/builders/lines.py +0 -0
  74. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/builders/manbuilder.py +0 -0
  75. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/eldef.py +0 -0
  76. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/maninfo.py +0 -0
  77. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/manoption.py +0 -0
  78. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/operations/__init__.py +0 -0
  79. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/operations/funopp.py +0 -0
  80. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/operations/itemopp.py +0 -0
  81. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/definition/operations/mathopp.py +0 -0
  82. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/__init__.py +0 -0
  83. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/autorotation.py +0 -0
  84. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/line.py +0 -0
  85. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/loop.py +0 -0
  86. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/nose_drop.py +0 -0
  87. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/pitch_break.py +0 -0
  88. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/recovery.py +0 -0
  89. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/elements/stall_turn.py +0 -0
  90. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/manoeuvre.py +0 -0
  91. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/schedule.py +0 -0
  92. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/__init__.py +0 -0
  93. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/__init__.py +0 -0
  94. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/criteria.py +0 -0
  95. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/inter/__init__.py +0 -0
  96. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scoring/criteria/intra/__init__.py +0 -0
  97. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scripts/batch_analyse.py +0 -0
  98. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis/scripts/plot_scores.py +0 -0
  99. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis.egg-info/dependency_links.txt +0 -0
  100. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis.egg-info/entry_points.txt +0 -0
  101. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/flightanalysis.egg-info/top_level.txt +0 -0
  102. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/pyproject.toml +0 -0
  103. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/AMA_Intermediate2024.py +0 -0
  104. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/__init__.py +0 -0
  105. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/create_all.py +0 -0
  106. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/f3a_a25.py +0 -0
  107. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/f3a_f25.py +0 -0
  108. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/f3a_p23.py +0 -0
  109. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/f3a_p25.py +0 -0
  110. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/f3auk_clubman.py +0 -0
  111. /flightanalysis-0.2.12/scripts/f3auk_Intermediate.py → /flightanalysis-0.2.14/scripts/f3auk_intermediate.py +0 -0
  112. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/imac_sport2024.py +0 -0
  113. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/imac_unlim2024.py +0 -0
  114. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/make_manoeuvre.py +0 -0
  115. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/scripts/nsrca_inter2024.py +0 -0
  116. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/setup.cfg +0 -0
  117. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/EmailedBox.f3a +0 -0
  118. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/__init__.py +0 -0
  119. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/conftest.py +0 -0
  120. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/data/manual_F3A_P23.json +0 -0
  121. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/data/p23.BIN +0 -0
  122. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/data/p23_box.f3a +0 -0
  123. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/data/p23_fc.json +0 -0
  124. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/data/p23_flight.json +0 -0
  125. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_criiteria.py +0 -0
  126. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_data.py +0 -0
  127. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/__init__.py +0 -0
  128. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_definition/__init__.py +0 -0
  129. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_definition/test_definition_eldef.py +0 -0
  130. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_definition/test_definition_manparm.py +0 -0
  131. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_definition/test_definition_mpopp.py +0 -0
  132. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_definition/test_schedule_definition.py +0 -0
  133. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_definition/test_schedule_definition_maninfo.py +0 -0
  134. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/__init__.py +0 -0
  135. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/loop_analysis.json +0 -0
  136. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/p23_th_e0.csv +0 -0
  137. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/p23_th_e0.json +0 -0
  138. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/p23_th_e0_template.csv +0 -0
  139. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/test_schedule_element.py +0 -0
  140. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/test_schedule_element_line.py +0 -0
  141. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/test_schedule_element_loop.py +0 -0
  142. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/test_schedule_element_nose_drop.py +0 -0
  143. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/test_schedule_element_pitch_break.py +0 -0
  144. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/test_schedule_element_recovery.py +0 -0
  145. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_element/test_schedule_element_stallturn.py +0 -0
  146. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_measurement.py +0 -0
  147. {flightanalysis-0.2.12 → flightanalysis-0.2.14}/tests/test_schedule/test_schedule_manoeuvre.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flightanalysis
3
- Version: 0.2.12
3
+ Version: 0.2.14
4
4
  Summary: A package for analysing flight data
5
5
  Author-email: Thomas David <thomasdavid0@gmail.com>
6
6
  License: GNU GPL v3
@@ -16,7 +16,7 @@ Requires-Dist: simplejson
16
16
  Requires-Dist: loguru
17
17
  Requires-Dist: joblib
18
18
  Requires-Dist: pfc-geometry>=0.2.6
19
- Requires-Dist: flightdata>=0.2.11
19
+ Requires-Dist: flightdata>=0.2.13
20
20
  Provides-Extra: dev
21
21
  Requires-Dist: numpy; extra == "dev"
22
22
  Requires-Dist: pandas; extra == "dev"
@@ -26,7 +26,7 @@ Requires-Dist: simplejson; extra == "dev"
26
26
  Requires-Dist: loguru; extra == "dev"
27
27
  Requires-Dist: joblib; extra == "dev"
28
28
  Requires-Dist: pfc-geometry>=0.2.6; extra == "dev"
29
- Requires-Dist: flightdata>=0.2.11; extra == "dev"
29
+ Requires-Dist: flightdata>=0.2.13; extra == "dev"
30
30
  Requires-Dist: ardupilot_log_reader>=0.3.1; extra == "dev"
31
31
  Requires-Dist: pymavlink; extra == "dev"
32
32
 
@@ -4,31 +4,31 @@ import numpy as np
4
4
 
5
5
  f3a=dict(
6
6
  single=dict(
7
- track=Single(Exponential.fit_points(np.radians([30, 90]), [2, 6], 100)),
8
- roll=Single(Exponential.fit_points(np.radians([30, 90]), [1, 6], 100)),
9
- angle=Single(Exponential.fit_points(np.radians([30, 90]), [2, 6], 100)),
7
+ track=Single(Exponential.fit_points(np.radians([30, 90]), [2, 6], 6)),
8
+ roll=Single(Exponential.fit_points(np.radians([30, 90]), [1, 6], 6)),
9
+ angle=Single(Exponential.fit_points(np.radians([30, 90]), [2, 6], 6)),
10
10
  # distance = Single(Exponential.fit_points([20, 40], [0.5, 1]))
11
11
  ),
12
12
  intra=dict(
13
- track=ContAbs(Exponential.fit_points(np.radians([30, 90]), [2, 6])),
14
- roll=ContAbs(Exponential.fit_points(np.radians([30, 90]), [1.5, 6])),
15
- radius=ContRat(Exponential.fit_points([1,5], [0.5, 4], 2)),
13
+ track=ContAbs(Exponential.fit_points(np.radians([30, 90]), [2, 6], 6)),
14
+ roll=ContAbs(Exponential.fit_points(np.radians([30, 90]), [1.5, 6], 6)),
15
+ radius=ContRat(Exponential.fit_points([1,5], [0.5, 4], 3)),
16
16
  speed=ContRat(Exponential.fit_points([1,5], [0.15, 0.75], 1)),
17
- roll_rate=ContRat(Exponential.fit_points([1,5], [0.15, 0.75], 1)),
17
+ roll_rate=ContRat(Exponential.fit_points([1,5], [0.15, 0.75], 2)),
18
18
  stallturn_speed=InsideBound(Exponential.fit_points([2, 5], [0.3,1.5]), [-2,2]),
19
19
  stallturn_width=InsideBound(Exponential.fit_points([2, 5], [0.5,2.5]), [-2,2]),
20
20
  spin_entry_length=InsideBound(Exponential.fit_points([2, 5], [0.3,1.5]), [-5,5]),
21
21
  pitch_break_length=InsideBound(Exponential.fit_points([1, 2], [0.7,3.5]), [-2,2]),
22
22
  nose_drop_amount=OutsideBound(Exponential(20,1), [-np.radians(15), np.radians(15)]),
23
23
  recovery_length=MaxBound(Exponential.fit_points([1, 2], [0.7,3.5]), 2),
24
- box=InsideBound(Exponential(10/np.radians(15), 1), [-np.radians(60), np.radians(60)]), # 10 points if the entire manoeuvre is 15 degrees outside the box
24
+ box=InsideBound(Exponential(10/np.radians(7.5), 1), [-np.radians(60), np.radians(60)]), # 10 points if the entire manoeuvre is 7.5 degrees outside the box
25
25
  depth=MaxBound(Exponential.fit_points([20, 40], [0.5, 1]), 170)
26
26
  ),
27
27
  inter=dict(
28
- radius=Comparison(Exponential.fit_points([1,5], [1, 2], 2)),
29
- speed=Comparison(Exponential.fit_points([1,5], [0.25, 1.0])),
30
- roll_rate=Comparison(Exponential.fit_points([1,5], [0.25, 1.5],2)),
31
- length=Comparison(Exponential.fit_points([1,5], [1, 3], 3)),
28
+ radius=Comparison(Exponential.fit_points([1,2], [1, 2], 2)),
29
+ speed=Comparison(Exponential.fit_points([1,2], [0.25, 0.5], 1)),
30
+ roll_rate=Comparison(Exponential.fit_points([1,2], [0.25, 0.5], 1)),
31
+ length=Comparison(Exponential.fit_points([1,2], [1, 2], 2)),
32
32
  free=Comparison(free),
33
33
  )
34
34
  )
@@ -47,7 +47,24 @@ def plot_lookup(lu, v0=0, v1=10):
47
47
  x = np.linspace(v0, v1, 30)
48
48
  px.line(x=x,y=lu(x)).show()
49
49
 
50
+ def plot_all(crits):
51
+ from plotly.subplots import make_subplots
52
+ import plotly.graph_objects as go
53
+ criteria = [cr for crit in crits.values() for cr in crit.values()]
54
+ names = [cr for crit in crits.values() for cr in crit.keys()]
55
+
56
+ nplots = sum([len(cr) for cr in crits.values()])
57
+ ncols=5
58
+ fig = make_subplots(int(np.ceil(nplots / ncols)), ncols, subplot_titles=names)
59
+
60
+ for i, crit in enumerate(criteria):
61
+ row, col = 1 + i // ncols, 1 + i % ncols
62
+ x = np.linspace(0, 10, 30)
63
+ fig.add_trace(go.Scatter(x=x, y=crit.lookup(x), showlegend=False), row=row, col=col)
64
+ fig.show()
65
+
50
66
  if __name__ == "__main__":
51
67
  #plot_lookup(f3a['intra']['recovery_length'].lookup,-10,10)
52
68
 
69
+ # plot_all(f3a)
53
70
  dump_criteria_to_py(f3a)
@@ -16,9 +16,9 @@ class ElementAnalysis:
16
16
  tp: State
17
17
  ref_frame: g.Transformation
18
18
 
19
- def plot_3d(self, origin=False, **kwargs):
19
+ def plot_3d(self, **kwargs):
20
20
  from flightplotting import plotsec
21
- return plotsec([self.fl, self.tp], 2, 5, origin=origin, **kwargs)
21
+ return plotsec([self.fl, self.tp], **kwargs)
22
22
 
23
23
  def to_dict(self):
24
24
  return {k: v.to_dict() for k, v in self.__dict__.items()}
@@ -0,0 +1,14 @@
1
+ from .analysis import Analysis
2
+ from .basic import Basic
3
+ from .alignment import Alignment
4
+ from .complete import Complete, Scored
5
+
6
+
7
+ def parse_dict(data: dict) -> Analysis:
8
+ return Scored.from_dict(data)
9
+
10
+ def parse(data: dict) -> Basic | Alignment | Complete | Scored:
11
+ if 'parameters' in data:
12
+ return Basic.from_mindict(data).proceed()
13
+ else:
14
+ return parse_dict(data).proceed()
@@ -0,0 +1,97 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass
3
+ from flightdata import State
4
+ from flightanalysis.manoeuvre import Manoeuvre
5
+ from loguru import logger
6
+ from .basic import Basic
7
+ from flightanalysis.definition import ManDef, ScheduleInfo
8
+ from ..el_analysis import ElementAnalysis
9
+
10
+ @dataclass
11
+ class Alignment(Basic):
12
+ manoeuvre: Manoeuvre | None
13
+ template: State | None
14
+
15
+ def __getattr__(self, name) -> ElementAnalysis:
16
+ return ElementAnalysis(
17
+ self.mdef.data[name],
18
+ self.mdef.mps,
19
+ self.manoeuvre.elements.data[name],
20
+ self.flown.get_element(name),
21
+ self.template.get_element(name),
22
+ self.template.get_element(name)[0].transform
23
+ )
24
+
25
+ def run_all(self, optimise_aligment=True, force=False) -> Alignment | Complete | Scored:
26
+ if self.__class__.__name__ == 'Scored' and force:
27
+ self = self.downgrade()
28
+ new = self
29
+ while self.__class__.__name__ != 'Scored':
30
+ new = self.run(optimise_aligment) if isinstance(self, Complete) else self.run()
31
+ if new.__class__.__name__ == self.__class__.__name__:
32
+ break
33
+ self = new
34
+ return new
35
+
36
+ @staticmethod
37
+ def from_dict(data: dict, fallback=True):
38
+ ia = Basic.from_dict(data)
39
+ try:
40
+ ia = Alignment(
41
+ manoeuvre=Manoeuvre.from_dict(data['manoeuvre']),
42
+ template=State.from_dict(data['template']),
43
+ **ia.__dict__
44
+ )
45
+ except Exception as e:
46
+ if fallback:
47
+ logger.debug(f'Failed to parse Alignment {repr(e)}')
48
+ else:
49
+ raise e
50
+ return ia
51
+
52
+ def run(self) -> Alignment | Complete:
53
+ if 'element' not in self.flown.data.columns:
54
+ try:
55
+ self = self._run(True)[1]
56
+ except Exception as e:
57
+ logger.error(f'Failed to run alignment stage 1: {repr(e)}')
58
+ return self
59
+ try:
60
+ return self._run(False)[1].proceed()
61
+ except Exception as e:
62
+ logger.error(f'Failed to run alignment stage 2: {repr(e)}')
63
+ return self
64
+
65
+ def _run(self, mirror=False, radius=10) -> Alignment:
66
+ dist, aligned = State.align(self.flown, self.template, radius, mirror)
67
+ return dist, self.update(aligned)
68
+
69
+ def update(self, aligned: State) -> Alignment:
70
+ man, tp = self.manoeuvre.match_intention(self.template[0], aligned)
71
+ mdef = ManDef(self.mdef.info, self.mdef.mps.update_defaults(man), self.mdef.eds)
72
+ return Alignment(self.id, mdef, aligned, self.direction, man, tp)
73
+
74
+ def _proceed(self) -> Complete:
75
+ if 'element' in self.flown.data.columns:
76
+ correction = self.mdef.create(self.template[0].transform)
77
+ return Complete(
78
+ self.id, self.mdef, self.flown, self.direction,
79
+ self.manoeuvre, self.template, correction,
80
+ correction.create_template(self.template[0], self.flown)
81
+ )
82
+ else:
83
+ return self
84
+
85
+ def to_mindict(self, sinfo: ScheduleInfo=None, full=False):
86
+ data = dict(
87
+ els = self.flown.label_ranges('element').to_dict('records')
88
+ )
89
+ if full:
90
+ data = dict(
91
+ **super().to_mindict(sinfo),
92
+ **data
93
+ )
94
+ return data
95
+
96
+ from .complete import Complete # noqa: E402
97
+ from .scored import Scored # noqa: E402
@@ -1,16 +1,16 @@
1
1
  from __future__ import annotations
2
2
  from dataclasses import dataclass
3
-
4
- class AlinmentStage:
5
- SETUP=0
6
- PRELIM=1
7
- SECONDARY=2
8
- OPTIMISED=3
9
-
3
+ from flightanalysis.definition import ScheduleInfo
10
4
 
11
5
  @dataclass
12
6
  class Analysis:
7
+ id: int
8
+
13
9
  def to_dict(self):
14
10
  return {k: (v.to_dict() if hasattr(v, 'to_dict') else v) for k, v in self.__dict__.items()}
15
11
 
16
-
12
+ def to_mindict(self, sinfo: ScheduleInfo):
13
+ return {
14
+ "sinfo": sinfo.__dict__,
15
+ }
16
+
@@ -0,0 +1,131 @@
1
+ from __future__ import annotations
2
+ from dataclasses import dataclass
3
+ from flightdata import State, Flight, Origin
4
+ from flightanalysis.definition import ManDef, SchedDef, ManOption
5
+ import geometry as g
6
+ from json import load
7
+ from .analysis import Analysis
8
+ from flightanalysis.definition.scheduleinfo import ScheduleInfo
9
+ import numpy as np
10
+ import pandas as pd
11
+
12
+
13
+ @dataclass
14
+ class Basic(Analysis):
15
+ mdef: ManDef | ManOption
16
+ flown: State
17
+ direction: int
18
+
19
+ @property
20
+ def name(self):
21
+ return self.mdef.uid
22
+
23
+ def run_all(self, optimise_aligment=True, force=False) -> Scored:
24
+ """Run the analysis to the final stage, for the case where the elements have not been labelled"""
25
+ drs = [r._run(True) for r in self.run()]
26
+
27
+ dr = drs[np.argmin([dr[0] for dr in drs])]
28
+
29
+ return dr[1].run_all(optimise_aligment, force)
30
+
31
+ def proceed(self) -> Complete:
32
+ """Proceed the analysis to the final stage for the case where the elements have already been labelled"""
33
+ if 'element' not in self.flown.data.columns:
34
+ return self
35
+ mopt = ManOption([self.mdef]) if isinstance(self.mdef, ManDef) else self.mdef
36
+ elnames = self.flown.data.element.unique()
37
+ for md in mopt:
38
+ if np.all(elnames[1:-1] == list( md.eds.data.keys())):
39
+ mdef = md
40
+ break
41
+ else:
42
+ raise ValueError(f"{self.mdef.info.short_name} element sequence doesn't agree with {self.flown.data.element.unique()}")
43
+
44
+ itrans = self.create_itrans()
45
+ man, tp = mdef.create(itrans).add_lines().match_intention(
46
+ State.from_transform(itrans),
47
+ self.flown
48
+ )
49
+ mdef = ManDef(mdef.info, mdef.mps.update_defaults(man), mdef.eds)
50
+ corr = mdef.create(itrans).add_lines()
51
+ return Complete(
52
+ self.id, mdef, self.flown, self.direction,
53
+ man, tp, corr, corr.create_template(itrans, self.flown)
54
+ )
55
+
56
+ @classmethod
57
+ def from_dict(Cls, data:dict) -> Basic:
58
+ return Basic(
59
+ -1,
60
+ ManDef.from_dict(data["mdef"]),
61
+ State.from_dict(data["flown"]),
62
+ data['direction']
63
+ )
64
+
65
+ def create_itrans(self) -> g.Transformation:
66
+ return g.Transformation(
67
+ self.flown[0].pos,
68
+ self.mdef.info.start.initial_rotation(self.direction)
69
+ )
70
+
71
+ @staticmethod
72
+ def from_fcj(file: str, mid: int):
73
+ with open(file, 'r') as f:
74
+ data = load(f)
75
+ flight = Flight.from_fc_json(data)
76
+ box = Origin.from_fcjson_parmameters(data["parameters"])
77
+
78
+ sdef = SchedDef.load(data["parameters"]["schedule"][1])
79
+
80
+ state = State.from_flight(flight, box).splitter_labels(
81
+ data["mans"],
82
+ [m.info.short_name for m in sdef]
83
+ )
84
+ mdef= sdef[mid]
85
+ return Basic(mid, mdef, state.get_manoeuvre(mdef.uid))
86
+
87
+ def run(self) -> list[Alignment]:
88
+ itrans = self.create_itrans()
89
+ mopt = ManOption([self.mdef]) if isinstance(self.mdef, ManDef) else self.mdef
90
+
91
+ als = []
92
+ for mdef in mopt:
93
+ man = mdef.create(itrans).add_lines()
94
+ als.append(Alignment(
95
+ self.id, mdef, self.flown, self.direction,
96
+ man, man.create_template(itrans)
97
+ ))
98
+ return als
99
+
100
+ def to_mindict(self, sinfo: ScheduleInfo):
101
+ data = dict(
102
+ **super().to_mindict(sinfo),
103
+ name=self.name,
104
+ id=self.id,
105
+ data=self.flown._create_json_data().to_dict('records'),
106
+ direction=self.direction,
107
+ )
108
+ return data
109
+
110
+ @staticmethod
111
+ def from_mindict(data: dict):
112
+ info = ScheduleInfo.from_str(data["parameters"]["schedule"][1])
113
+
114
+ st = State.from_flight(
115
+ Flight.from_fc_json(data),
116
+ Origin.from_fcjson_parmameters(data["parameters"])
117
+ )
118
+
119
+ mdef = SchedDef.load(info)[data['id']]
120
+
121
+ if 'els' in data:
122
+ df = pd.DataFrame(data['els'])
123
+ df.columns = ['name', 'start', 'stop', 'length']
124
+ st = st.splitter_labels(df.to_dict('records'), target_col='element').label(manoeuvre=data['name'])
125
+
126
+ return Basic(data['id'], mdef, st, data['direction'])
127
+
128
+
129
+ from .alignment import Alignment # noqa: E402
130
+ from .complete import Complete # noqa: E402
131
+ from .scored import Scored # noqa: E402
@@ -2,13 +2,13 @@ from __future__ import annotations
2
2
  from dataclasses import dataclass
3
3
  from ..el_analysis import ElementAnalysis
4
4
  from flightdata import State
5
- from flightanalysis.definition import ManDef
5
+ from flightanalysis.definition import ManDef, ScheduleInfo
6
6
  from flightanalysis.manoeuvre import Manoeuvre
7
7
  from flightanalysis.scoring import Results, ManoeuvreResults, Measurement
8
8
  from flightanalysis.scoring.criteria.f3a_criteria import F3A
9
9
  from flightanalysis.definition.maninfo import Position
10
10
  import numpy as np
11
- from .alignment import Alignment, AlinmentStage
11
+ from .alignment import Alignment
12
12
  from loguru import logger
13
13
 
14
14
 
@@ -34,7 +34,7 @@ class Complete(Alignment):
34
34
  return pa
35
35
 
36
36
  def run(self, optimise_aligment=True) -> Scored:
37
- if self.stage < AlinmentStage.OPTIMISED and optimise_aligment:
37
+ if optimise_aligment:
38
38
  self = self.optimise_alignment()
39
39
  self = self.update_templates()
40
40
  return Scored(**self.__dict__,
@@ -63,6 +63,7 @@ class Complete(Alignment):
63
63
  tp = el.get_data(self.template).relocate(st.pos[0])
64
64
  return ElementAnalysis(edef, self.mdef.mps, el, st, tp, el.ref_frame(tp))
65
65
 
66
+
66
67
  def update_templates(self):
67
68
  if not np.all(self.flown.element == self.template.element):
68
69
  manoeuvre, template = self.manoeuvre.match_intention(self.template[0], self.flown)
@@ -70,8 +71,9 @@ class Complete(Alignment):
70
71
  correction = mdef.create(self.template[0].transform).add_lines()
71
72
 
72
73
  return Complete(
73
- mdef, self.flown, self.direction, AlinmentStage.OPTIMISED, self.dist,
74
- manoeuvre, template, correction, correction.create_template(template[0])
74
+ self.id, mdef, self.flown, self.direction,
75
+ manoeuvre, template, correction,
76
+ correction.create_template(template[0])
75
77
  )
76
78
  else:
77
79
  return self
@@ -127,13 +129,6 @@ class Complete(Alignment):
127
129
  Measurement.depth(self.flown)
128
130
  )
129
131
 
130
- # val = self.flown.pos.y.mean()
131
- # id = np.abs(self.flown.pos.y - val).argmin()
132
- # m = Measurement.depth(self.flown[id])
133
- # error = np.maximum(m.value, 170) - 170
134
- # dist_dg = F3A.single.distance.lookup(error) * m.visibility
135
- # return Result("distance", m, m.value, error, dist_dg, [id])
136
-
137
132
  def intra(self):
138
133
  return self.manoeuvre.analyse(self.flown, self.template)
139
134
 
@@ -160,4 +155,6 @@ class Complete(Alignment):
160
155
  fig = plotdtw(self.flown, self.flown.data.element.unique())
161
156
  return plotsec(self.flown, color="blue", nmodels=20, fig=fig, **kwargs)
162
157
 
158
+
159
+
163
160
  from .scored import Scored # noqa: E402
@@ -1,6 +1,7 @@
1
1
  from dataclasses import dataclass
2
2
  from .complete import Complete
3
3
  from flightanalysis.scoring import ManoeuvreResults
4
+ from flightanalysis.definition.scheduleinfo import ScheduleInfo
4
5
  from loguru import logger
5
6
 
6
7
 
@@ -8,6 +9,13 @@ from loguru import logger
8
9
  class Scored(Complete):
9
10
  scores: ManoeuvreResults
10
11
 
12
+ def downgrade(self) -> Complete:
13
+ return Complete(
14
+ self.id, self.mdef, self.flown, self.direction,
15
+ self.manoeuvre, self.template, self.corrected,
16
+ self.corrected_template
17
+ )
18
+
11
19
  @staticmethod
12
20
  def from_dict(data:dict, fallback=True):
13
21
  ca = Complete.from_dict(data, fallback)
@@ -22,6 +30,16 @@ class Scored(Complete):
22
30
  else:
23
31
  raise e
24
32
  return ca
25
-
26
- def run(self, optimise_alignment=True):
27
- return self
33
+
34
+ def to_mindict(self, sinfo: ScheduleInfo=None, full=False):
35
+ data = dict(
36
+ **super().to_mindict(sinfo, full),
37
+ scores=dict(
38
+ **self.scores.summary(),
39
+ total=self.scores.score(),
40
+ k=self.mdef.info.k
41
+ )
42
+ )
43
+
44
+ return data
45
+
@@ -41,16 +41,15 @@ class ScheduleAnalysis(Collection):
41
41
 
42
42
  return ScheduleAnalysis(
43
43
  [analysis.Basic(
44
+ i,
44
45
  mdef,
45
46
  state.get_manoeuvre(mdef.uid),
46
- direction,
47
- analysis.AlinmentStage.SETUP
48
- ) for mdef in sdef],
47
+ direction
48
+ ) for i, mdef in enumerate(sdef)],
49
49
  info
50
50
  )
51
51
 
52
52
  def run_all(self) -> Self:
53
-
54
53
  def parse_analyse_serialise(pad):
55
54
  res = analysis.Basic.from_dict(pad).run_all()
56
55
  logger.info(f'Completed {res.name}')
@@ -67,7 +66,6 @@ class ScheduleAnalysis(Collection):
67
66
 
68
67
  def parse_analyse_serialise(mad):
69
68
  an = analysis.Complete.from_dict(mad)
70
- an.stage = analysis.AlinmentStage.SECONDARY
71
69
  return an.run_all().to_dict()
72
70
 
73
71
  logger.info(f'Starting {os.cpu_count()} alinment optimisation processes')