patkit 0.22.0__tar.gz → 0.22.2__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 (120) hide show
  1. {patkit-0.22.0 → patkit-0.22.2}/PKG-INFO +21 -17
  2. {patkit-0.22.0 → patkit-0.22.2}/README.md +20 -8
  3. {patkit-0.22.0 → patkit-0.22.2}/patkit/__init__.py +1 -1
  4. {patkit-0.22.0 → patkit-0.22.2}/patkit/cli_commands.py +89 -0
  5. {patkit-0.22.0 → patkit-0.22.2}/patkit/configuration/configuration.py +4 -3
  6. {patkit-0.22.0 → patkit-0.22.2}/patkit/constants.py +95 -8
  7. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_structures/__init__.py +1 -1
  8. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_structures/base_classes.py +21 -20
  9. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_structures/data_structures.py +131 -31
  10. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_structures/metadata_classes.py +49 -1
  11. {patkit-0.22.0 → patkit-0.22.2}/patkit/get_modality_types.py +5 -4
  12. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/__init__.py +4 -0
  13. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/annotator_window.py +103 -35
  14. patkit-0.22.2/patkit/gui/audio_player.py +141 -0
  15. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/boundary_animation.py +4 -4
  16. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/dialog_template.py +3 -3
  17. patkit-0.22.2/patkit/gui/exercise_dialogs.py +190 -0
  18. patkit-0.22.2/patkit/gui/list_selection_dialog.py +115 -0
  19. patkit-0.22.2/patkit/gui/plot_controller.py +905 -0
  20. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/select_scenario_dialog.py +5 -3
  21. {patkit-0.22.0 → patkit-0.22.2}/patkit/import_formats/avi_read.py +14 -11
  22. {patkit-0.22.0 → patkit-0.22.2}/patkit/initialise.py +6 -6
  23. {patkit-0.22.0 → patkit-0.22.2}/patkit/patgrid.py +18 -4
  24. patkit-0.22.2/patkit/path_resolution.py +161 -0
  25. {patkit-0.22.0 → patkit-0.22.2}/patkit/plot_and_publish/__init__.py +2 -1
  26. {patkit-0.22.0 → patkit-0.22.2}/patkit/qt_annotator.py +437 -852
  27. {patkit-0.22.0 → patkit-0.22.2}/patkit/save_and_load/__init__.py +7 -2
  28. {patkit-0.22.0 → patkit-0.22.2}/patkit/save_and_load/load.py +115 -9
  29. {patkit-0.22.0 → patkit-0.22.2}/patkit/save_and_load/save.py +85 -11
  30. {patkit-0.22.0 → patkit-0.22.2}/patkit/save_and_load/save_and_load_schemas.py +31 -1
  31. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/simulate.py +3 -2
  32. {patkit-0.22.0 → patkit-0.22.2}/patkit/ui_callbacks.py +1 -1
  33. {patkit-0.22.0 → patkit-0.22.2}/pyproject.toml +25 -9
  34. patkit-0.22.0/patkit/gui/open_answer_dialog.py +0 -136
  35. {patkit-0.22.0 → patkit-0.22.2}/.gitignore +0 -0
  36. {patkit-0.22.0 → patkit-0.22.2}/LICENSE.markdown +0 -0
  37. {patkit-0.22.0 → patkit-0.22.2}/patkit/annotations/__init__.py +0 -0
  38. {patkit-0.22.0 → patkit-0.22.2}/patkit/annotations/peaks.py +0 -0
  39. {patkit-0.22.0 → patkit-0.22.2}/patkit/audio_processing/__init__.py +0 -0
  40. {patkit-0.22.0 → patkit-0.22.2}/patkit/audio_processing/audio_processing.py +0 -0
  41. {patkit-0.22.0 → patkit-0.22.2}/patkit/cli.py +0 -0
  42. {patkit-0.22.0 → patkit-0.22.2}/patkit/computational.py +0 -0
  43. {patkit-0.22.0 → patkit-0.22.2}/patkit/configuration/__init__.py +0 -0
  44. {patkit-0.22.0 → patkit-0.22.2}/patkit/configuration/configuration_models.py +0 -0
  45. {patkit-0.22.0 → patkit-0.22.2}/patkit/configuration/configuration_parsers.py +0 -0
  46. {patkit-0.22.0 → patkit-0.22.2}/patkit/configuration/exclusion_list_functions.py +0 -0
  47. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/AAA_raw_ultrasound.py +0 -0
  48. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/AAA_recordings.py +0 -0
  49. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/AAA_splines.py +0 -0
  50. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/RASL_3D_ultrasound_recordings.py +0 -0
  51. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/__init__.py +0 -0
  52. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/audio.py +0 -0
  53. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/session_import_config.py +0 -0
  54. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/spline_import_config.py +0 -0
  55. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/three_dim_ultrasound.py +0 -0
  56. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/video.py +0 -0
  57. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_import/wav_recordings.py +0 -0
  58. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_loader.py +0 -0
  59. {patkit-0.22.0 → patkit-0.22.2}/patkit/data_processor.py +0 -0
  60. {patkit-0.22.0 → patkit-0.22.2}/patkit/default_configuration/patkit-data.yaml +0 -0
  61. {patkit-0.22.0 → patkit-0.22.2}/patkit/default_configuration/patkit-gui.yaml +0 -0
  62. {patkit-0.22.0 → patkit-0.22.2}/patkit/default_configuration/patkit-publish.yaml +0 -0
  63. {patkit-0.22.0 → patkit-0.22.2}/patkit/default_configuration/patkit_logging_configuration.json +0 -0
  64. {patkit-0.22.0 → patkit-0.22.2}/patkit/errors.py +0 -0
  65. {patkit-0.22.0 → patkit-0.22.2}/patkit/export/__init__.py +0 -0
  66. {patkit-0.22.0 → patkit-0.22.2}/patkit/export/images.py +0 -0
  67. {patkit-0.22.0 → patkit-0.22.2}/patkit/export/metadata.py +0 -0
  68. {patkit-0.22.0 → patkit-0.22.2}/patkit/export/modality_data.py +0 -0
  69. {patkit-0.22.0 → patkit-0.22.2}/patkit/external_class_extensions/__init__.py +0 -0
  70. {patkit-0.22.0 → patkit-0.22.2}/patkit/external_class_extensions/base_model_extensions.py +0 -0
  71. {patkit-0.22.0 → patkit-0.22.2}/patkit/external_class_extensions/enum_extensions.py +0 -0
  72. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/image_save_dialog.py +0 -0
  73. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/list_save_dialog.py +0 -0
  74. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/ofbrowse.py +0 -0
  75. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/player_controls.py +0 -0
  76. {patkit-0.22.0 → patkit-0.22.2}/patkit/gui/replace_dialog.py +0 -0
  77. {patkit-0.22.0 → patkit-0.22.2}/patkit/import_formats/__init__.py +0 -0
  78. {patkit-0.22.0 → patkit-0.22.2}/patkit/import_formats/dicom_ultra_read.py +0 -0
  79. {patkit-0.22.0 → patkit-0.22.2}/patkit/import_formats/rasl_dat_to_wav.py +0 -0
  80. {patkit-0.22.0 → patkit-0.22.2}/patkit/import_formats/splines_read.py +0 -0
  81. {patkit-0.22.0 → patkit-0.22.2}/patkit/import_formats/ult_read.py +0 -0
  82. {patkit-0.22.0 → patkit-0.22.2}/patkit/import_formats/wav_read.py +0 -0
  83. {patkit-0.22.0 → patkit-0.22.2}/patkit/interpolate_raw_uti.py +0 -0
  84. {patkit-0.22.0 → patkit-0.22.2}/patkit/interpreter.py +0 -0
  85. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/__init__.py +0 -0
  86. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/aggregate_image.py +0 -0
  87. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/calculate_aggregate_images.py +0 -0
  88. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/calculate_distance_matrices.py +0 -0
  89. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/calculate_intensity.py +0 -0
  90. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/calculate_pd.py +0 -0
  91. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/calculate_spline_metric.py +0 -0
  92. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/distance_matrix.py +0 -0
  93. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/downsample_metric.py +0 -0
  94. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/intensity.py +0 -0
  95. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/metrics_helpers.py +0 -0
  96. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/ofreg.py +0 -0
  97. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/pd.py +0 -0
  98. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/spline_metric.py +0 -0
  99. {patkit-0.22.0 → patkit-0.22.2}/patkit/metrics/tongue_shape_analysis.py +0 -0
  100. {patkit-0.22.0 → patkit-0.22.2}/patkit/modalities/__init__.py +0 -0
  101. {patkit-0.22.0 → patkit-0.22.2}/patkit/modalities/recorded_metadata_classes.py +0 -0
  102. {patkit-0.22.0 → patkit-0.22.2}/patkit/modalities/recorded_modalities.py +0 -0
  103. {patkit-0.22.0 → patkit-0.22.2}/patkit/modalities/splines.py +0 -0
  104. {patkit-0.22.0 → patkit-0.22.2}/patkit/plot_and_publish/legend_generation.py +0 -0
  105. {patkit-0.22.0 → patkit-0.22.2}/patkit/plot_and_publish/plot.py +0 -0
  106. {patkit-0.22.0 → patkit-0.22.2}/patkit/plot_and_publish/plot_utilities.py +0 -0
  107. {patkit-0.22.0 → patkit-0.22.2}/patkit/plot_and_publish/publish.py +0 -0
  108. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/__init__.py +0 -0
  109. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/contour_tools.py +0 -0
  110. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/metric_calculations.py +0 -0
  111. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/perturbation_series_plots.py +0 -0
  112. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/rays_on_contours.py +0 -0
  113. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/simulation_datastructures.py +0 -0
  114. {patkit-0.22.0 → patkit-0.22.2}/patkit/simulation/simulation_plots.py +0 -0
  115. {patkit-0.22.0 → patkit-0.22.2}/patkit/utility_functions/__init__.py +0 -0
  116. {patkit-0.22.0 → patkit-0.22.2}/patkit/utility_functions/logging_helpers.py +0 -0
  117. {patkit-0.22.0 → patkit-0.22.2}/patkit/utility_functions/path.py +0 -0
  118. {patkit-0.22.0 → patkit-0.22.2}/patkit/utility_functions/processing_helpers.py +0 -0
  119. {patkit-0.22.0 → patkit-0.22.2}/patkit/utility_functions/string_formatters.py +0 -0
  120. {patkit-0.22.0 → patkit-0.22.2}/patkit/utility_functions/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patkit
3
- Version: 0.22.0
3
+ Version: 0.22.2
4
4
  Summary: Phonetic Analysis ToolKit: Tools for processing phonetic data
5
5
  Project-URL: bug_tracker, https://github.com/giuthas/patkit/issues
6
6
  Project-URL: changelog, https://github.com/giuthas/patkit/blob/main/docs/Release_notes.markdown
@@ -691,41 +691,34 @@ Classifier: Development Status :: 3 - Alpha
691
691
  Classifier: Programming Language :: Python
692
692
  Requires-Python: >=3.10.13
693
693
  Requires-Dist: bioread>=3.0.1
694
- Requires-Dist: build>=1.2.2.post1
695
694
  Requires-Dist: click-default-group>=1.2.4
696
695
  Requires-Dist: click>=8.1.8
697
- Requires-Dist: deepdiff>=8.6.2
698
696
  Requires-Dist: dipy>=1.10.0
699
697
  Requires-Dist: fonttools>=4.55.3
700
- Requires-Dist: icecream>=2.1.3
701
698
  Requires-Dist: jinja2>=3.1.5
702
- Requires-Dist: licenseheaders>=0.8.8
703
699
  Requires-Dist: matplotlib>=3.10.0
704
700
  Requires-Dist: more-itertools>=10.5.0
705
701
  Requires-Dist: mpl-point-clicker>=0.4.1
706
702
  Requires-Dist: nestedtext>=3.7
707
703
  Requires-Dist: numpy>=2.2.1
708
- Requires-Dist: pdoc>=15.0.1
709
704
  Requires-Dist: pillow>=12.2.0
710
705
  Requires-Dist: praat-textgrids>=1.4.0
711
706
  Requires-Dist: pydantic>=2.10.4
712
707
  Requires-Dist: pydicom>=3.0.2
713
- Requires-Dist: pylint>=3.3.3
714
708
  Requires-Dist: pyqt6>=6.10.0
715
709
  Requires-Dist: pyreadline3>=3.5.4; platform_system == 'Windows'
716
710
  Requires-Dist: qbstyles>=0.1.4
717
711
  Requires-Dist: scipy>=1.15.0
718
712
  Requires-Dist: seaborn>=0.13.2
719
- Requires-Dist: setuptools>=75.7.0
720
713
  Requires-Dist: sk-video>=1.1.10
721
714
  Requires-Dist: sounddevice>=0.5.5
722
715
  Requires-Dist: strictyaml>=1.7.3
723
- Requires-Dist: virtualenv>=20.28.1
724
716
  Description-Content-Type: text/markdown
725
717
 
718
+ [![test](https://github.com/giuthas/patkit/actions/workflows/test.yaml/badge.svg)](https://github.com/giuthas/patkit/actions/workflows/test.yaml)
726
719
  # PATKIT - Phonetic Analysis ToolKIT
727
720
 
728
- ![PATKIT GUI](https://giuthas.github.io/patkit/PATKIT_UI_0.20.1.png)
721
+ ![PATKIT GUI](https://giuthas.github.io/patkit/PATKIT_UI_0.22.0.png)
729
722
 
730
723
  PATKIT provides tools for phonetic analysis of speech data. It includes a GUI
731
724
  for manual assessment/analysis/annotation (see picture above), command line
@@ -756,10 +749,7 @@ thesis](https://eresearch.qmu.ac.uk/handle/20.500.12289/10163).
756
749
  - See [uv](https://docs.astral.sh/uv/#getting-started) for more details.
757
750
  - On the commandline run `uv tool install patkit`
758
751
  - Run `patkit --help` for instructions.
759
- - If you want to run the example data, get the `recorded_data` and `scenarios` folders from
760
- [github](https://github.com/giuthas/patkit).
761
- - Run `patkit scenarios/minimal` in the folder where you downloaded the data
762
- and experiment from there.
752
+ - If you want to run the example data, see 'What's included' below for instructions.
763
753
 
764
754
  - If on Linux of the debian variety (ubuntu, popos, others), you may also need
765
755
  to run the following:
@@ -776,13 +766,27 @@ Try this in case trying to run patkit complains about a missing `xcb` plugin.
776
766
 
777
767
  ## Current version and development plans
778
768
 
779
- See [Changelog](https://giuthas.github.io/patkit/Changelog), for what's new in the current version
780
- and what's coming up.
769
+ See [Changelog](https://giuthas.github.io/patkit/Changelog), for what's new in
770
+ the current version and what's coming up.
781
771
 
782
772
 
783
773
  ## What's included
784
774
 
785
- TODO 0.22.1: give a quick description of included data and goodies here.
775
+ There is some test and demo data that is temporarily hosted in the GitHub repo.
776
+ Download the contents of
777
+ `https://github.com/giuthas/patkit/tree/main/recorded_data/` and
778
+ `https://github.com/giuthas/patkit/tree/main/scenarios/`. Easiest way to do
779
+ this is by copy-pasting the URLs to [this
780
+ page](https://download-directory.github.io/) to get a zip file with the
781
+ contents of the directory.
782
+
783
+ Place the unzipped directories in the same directory and after installing
784
+ patkit try running
785
+ ```
786
+ patkit scenarios/minimal
787
+ ```
788
+ and experiment from there.
789
+
786
790
  TODO 1.0: Move the data elsewhere to be optionally loaded.
787
791
 
788
792
  ## Contributing
@@ -1,6 +1,7 @@
1
+ [![test](https://github.com/giuthas/patkit/actions/workflows/test.yaml/badge.svg)](https://github.com/giuthas/patkit/actions/workflows/test.yaml)
1
2
  # PATKIT - Phonetic Analysis ToolKIT
2
3
 
3
- ![PATKIT GUI](https://giuthas.github.io/patkit/PATKIT_UI_0.20.1.png)
4
+ ![PATKIT GUI](https://giuthas.github.io/patkit/PATKIT_UI_0.22.0.png)
4
5
 
5
6
  PATKIT provides tools for phonetic analysis of speech data. It includes a GUI
6
7
  for manual assessment/analysis/annotation (see picture above), command line
@@ -31,10 +32,7 @@ thesis](https://eresearch.qmu.ac.uk/handle/20.500.12289/10163).
31
32
  - See [uv](https://docs.astral.sh/uv/#getting-started) for more details.
32
33
  - On the commandline run `uv tool install patkit`
33
34
  - Run `patkit --help` for instructions.
34
- - If you want to run the example data, get the `recorded_data` and `scenarios` folders from
35
- [github](https://github.com/giuthas/patkit).
36
- - Run `patkit scenarios/minimal` in the folder where you downloaded the data
37
- and experiment from there.
35
+ - If you want to run the example data, see 'What's included' below for instructions.
38
36
 
39
37
  - If on Linux of the debian variety (ubuntu, popos, others), you may also need
40
38
  to run the following:
@@ -51,13 +49,27 @@ Try this in case trying to run patkit complains about a missing `xcb` plugin.
51
49
 
52
50
  ## Current version and development plans
53
51
 
54
- See [Changelog](https://giuthas.github.io/patkit/Changelog), for what's new in the current version
55
- and what's coming up.
52
+ See [Changelog](https://giuthas.github.io/patkit/Changelog), for what's new in
53
+ the current version and what's coming up.
56
54
 
57
55
 
58
56
  ## What's included
59
57
 
60
- TODO 0.22.1: give a quick description of included data and goodies here.
58
+ There is some test and demo data that is temporarily hosted in the GitHub repo.
59
+ Download the contents of
60
+ `https://github.com/giuthas/patkit/tree/main/recorded_data/` and
61
+ `https://github.com/giuthas/patkit/tree/main/scenarios/`. Easiest way to do
62
+ this is by copy-pasting the URLs to [this
63
+ page](https://download-directory.github.io/) to get a zip file with the
64
+ contents of the directory.
65
+
66
+ Place the unzipped directories in the same directory and after installing
67
+ patkit try running
68
+ ```
69
+ patkit scenarios/minimal
70
+ ```
71
+ and experiment from there.
72
+
61
73
  TODO 1.0: Move the data elsewhere to be optionally loaded.
62
74
 
63
75
  ## Contributing
@@ -56,7 +56,7 @@ from .cli import run_cli
56
56
  from .initialise import add_derived_data, initialise_patkit
57
57
  from .qt_annotator import run_annotator
58
58
 
59
- # __all__ = ['add_derived_data', 'initialise_patkit']
59
+ __all__ = ['add_derived_data', 'initialise_patkit', 'run_cli', 'run_annotator']
60
60
 
61
61
  # Load logging config from json file.
62
62
  LOG_CONFIG = "patkit_logging_configuration.json"
@@ -37,13 +37,57 @@ from pathlib import Path
37
37
 
38
38
  import click
39
39
 
40
+ from patkit.constants import OpenPathType
40
41
  from patkit.initialise import initialise_config, initialise_patkit
42
+ from patkit.path_resolution import get_manifest_scenarios, resolve_open_path
41
43
  from patkit.qt_annotator import run_annotator
42
44
  from patkit.interpreter import run_interpreter
43
45
  from patkit.simulation import run_simulations
44
46
  from patkit.simulation.simulate import setup_contours_comparisons_soundpairs
45
47
 
46
48
 
49
+ def resolve_scenario_path(path: Path) -> Path:
50
+ """
51
+ CLI-specific path resolution that prompts the user via the terminal.
52
+
53
+ Parameters
54
+ ----------
55
+ path : Path
56
+ The original target path provided by the user.
57
+
58
+ Returns
59
+ -------
60
+ Path
61
+ The chosen scenario path, or the original path if none apply.
62
+ """
63
+ scenarios = get_manifest_scenarios(path=path)
64
+
65
+ if not scenarios:
66
+ return path
67
+
68
+ if len(scenarios) == 1:
69
+ click.echo(
70
+ f"Automatically opening the single scenario from "
71
+ f"manifest: {scenarios[0]}"
72
+ )
73
+ return scenarios[0]
74
+
75
+ click.echo("\nMultiple scenarios found in the manifest file:")
76
+ for idx, s_path in enumerate(scenarios, 1):
77
+ click.echo(f" [{idx}] {s_path}")
78
+
79
+ choice = click.prompt(
80
+ "\nPlease select which scenario you want to open",
81
+ type=click.IntRange(1, len(scenarios)),
82
+ default=1
83
+ )
84
+
85
+ chosen_path = scenarios[choice - 1]
86
+ click.echo(f"Opening selected scenario: {chosen_path}\n")
87
+
88
+ return chosen_path
89
+
90
+
47
91
  @click.command(name="open")
48
92
  @click.argument(
49
93
  "path",
@@ -60,6 +104,28 @@ def open_in_annotator(
60
104
  \b
61
105
  PATH to the data - maybe be a file or a directory.
62
106
  """
107
+ path_type, path = resolve_open_path(path)
108
+ match path_type:
109
+ case OpenPathType.MANIFEST:
110
+ path = resolve_scenario_path(path=path)
111
+ case OpenPathType.SCENARIO:
112
+ pass
113
+ case OpenPathType.DIRECTORY:
114
+ raise NotImplementedError(
115
+ "Opening a directory of data without "
116
+ "config is not implemented yet."
117
+ )
118
+ case OpenPathType.SINGLE_DATA:
119
+ raise NotImplementedError(
120
+ "Opening a single data file without "
121
+ "config is not implemented yet."
122
+ )
123
+ case _:
124
+ raise NotImplementedError(
125
+ f"Unimplemented type of load path "
126
+ f"{path_type}."
127
+ )
128
+
63
129
  config, logger = initialise_config(
64
130
  path=path, require_gui=True, require_data=True)
65
131
  session = initialise_patkit(config=config, logger=logger)
@@ -81,6 +147,28 @@ def interact(
81
147
  \b
82
148
  PATH to the data - maybe be a file or a directory.
83
149
  """
150
+ path_type, path = resolve_open_path(path)
151
+ match path_type:
152
+ case OpenPathType.MANIFEST:
153
+ path = resolve_scenario_path(path=path)
154
+ case OpenPathType.SCENARIO:
155
+ pass
156
+ case OpenPathType.DIRECTORY:
157
+ raise NotImplementedError(
158
+ "Opening a directory of data without "
159
+ "config is not implemented yet."
160
+ )
161
+ case OpenPathType.SINGLE_DATA:
162
+ raise NotImplementedError(
163
+ "Opening a single data file without "
164
+ "config is not implemented yet."
165
+ )
166
+ case _:
167
+ raise NotImplementedError(
168
+ f"Unimplemented type of load path "
169
+ f"{path_type}."
170
+ )
171
+
84
172
  config, logger = initialise_config(path=path, require_data=True)
85
173
  session = initialise_patkit(config=config, logger=logger)
86
174
  run_interpreter(session=session, configuration=config)
@@ -101,6 +189,7 @@ def publish(path: Path):
101
189
 
102
190
  NOT IMPLEMENTED YET.
103
191
  """
192
+ path = resolve_scenario_path(path=path)
104
193
  config, logger = initialise_config(path=path, require_publish=True)
105
194
  session = initialise_patkit(config=config, logger=logger)
106
195
  print(
@@ -85,7 +85,7 @@ class ConfigPaths:
85
85
 
86
86
  class Configuration:
87
87
  """
88
- Main configuration class of patkit.
88
+ Main configuration class of patkit.
89
89
  """
90
90
 
91
91
  # TODO: implement save functionality.
@@ -95,7 +95,7 @@ class Configuration:
95
95
  configuration_paths: ConfigPaths
96
96
  ) -> None:
97
97
  """
98
- Init the main configuration object.
98
+ Init the main configuration object.
99
99
 
100
100
  Run only once. Updates should be done with methods of the class.
101
101
 
@@ -113,7 +113,8 @@ class Configuration:
113
113
  self._data_yaml = load_data_params(
114
114
  self._config_paths.data_config)
115
115
  self._data_config = DataConfig(**self._data_yaml.data)
116
- recorded = self._config_paths.path/self._data_config.recorded_data_path
116
+ recorded = \
117
+ self._config_paths.path/self._data_config.recorded_data_path
117
118
  self._data_config.recorded_data_path = recorded.resolve()
118
119
  else:
119
120
  self._data_config = None
@@ -39,7 +39,6 @@ values and avoids typos and makes an IDE help in writing code.
39
39
  Frozen dataclasses are used for constants that only ever need to be accessed
40
40
  and never are stored. In effect, they function as look-up tables.
41
41
  """
42
- from dataclasses import dataclass
43
42
  from enum import Enum
44
43
  from importlib.metadata import version
45
44
 
@@ -50,6 +49,7 @@ from patkit.external_class_extensions import (
50
49
  # TODO 1.0: Decouple program and file format versions at version 1.0.
51
50
  PATKIT_VERSION = version('patkit')
52
51
  PATKIT_FILE_VERSION = PATKIT_VERSION
52
+ EXERCISE_FILE_VERSION = PATKIT_VERSION
53
53
 
54
54
  DEFAULT_ENCODING = 'utf-8'
55
55
 
@@ -169,8 +169,7 @@ class IntervalCategory(Enum):
169
169
  LAST_LABELED = 'last labeled'
170
170
 
171
171
 
172
- @dataclass(frozen=True)
173
- class PatkitConfigFile:
172
+ class PatkitConfigFile(str, Enum):
174
173
  """
175
174
  Human written yaml files to control importing data.
176
175
 
@@ -194,6 +193,7 @@ class PatkitConfigFile:
194
193
  SESSION: how PATKIT should read a session based on recorded data
195
194
  SPLINE: spline formatting
196
195
  """
196
+ ANSWER = "patkit-answer.yaml"
197
197
  EXERCISE = "patkit-exercise.yaml"
198
198
  DATA = "patkit-data.yaml"
199
199
  GUI = "patkit-gui.yaml"
@@ -203,9 +203,29 @@ class PatkitConfigFile:
203
203
  SESSION = 'session-config.yaml'
204
204
  SPLINE = 'spline-config.yaml'
205
205
 
206
+ def __str__(self) -> str:
207
+ """
208
+ Ensure f-strings and print() output the string value.
209
+ """
210
+ return self.value
211
+
212
+
213
+ class PatkitDirectory(str, Enum):
214
+ """
215
+ Standard directory names used in PATKIT.
216
+ """
217
+ ANSWERS = "answers"
218
+ EXAMPLE = "example"
219
+ EXERCISE = "exercise"
220
+
221
+ def __str__(self) -> str:
222
+ """
223
+ Ensure f-strings and print() output the string value.
224
+ """
225
+ return self.value
226
+
206
227
 
207
- @dataclass(frozen=True)
208
- class PatkitSuffix:
228
+ class PatkitSuffix(str, Enum):
209
229
  """
210
230
  Suffixes for files saved by patkit.
211
231
 
@@ -217,12 +237,18 @@ class PatkitSuffix:
217
237
  DATA = ".npz"
218
238
  META = ".meta"
219
239
 
240
+ def __str__(self) -> str:
241
+ """
242
+ Ensure f-strings and print() output the string value.
243
+ """
244
+ return self.value
245
+
220
246
 
221
247
  class SavedObjectTypes(Enum):
222
248
  """
223
249
  Represent type of a saved patkit object in .meta.
224
250
  """
225
- # TODO 1.0: Check if this is actually in use.
251
+ EXERCISE = "Exercise"
226
252
  DATASET = "Dataset"
227
253
  MODALITY = "Modality"
228
254
  RECORDING = "Recording"
@@ -232,8 +258,7 @@ class SavedObjectTypes(Enum):
232
258
  TRIAL = "Trial"
233
259
 
234
260
 
235
- @dataclass(frozen=True)
236
- class SourceSuffix:
261
+ class SourceSuffix(str, Enum):
237
262
  """
238
263
  Suffixes for files imported by patkit.
239
264
 
@@ -257,6 +282,22 @@ class SourceSuffix:
257
282
  TEXTGRID = ".TextGrid"
258
283
  WAV = ".wav"
259
284
 
285
+ def __str__(self) -> str:
286
+ """
287
+ Ensure f-strings and print() output the string value.
288
+ """
289
+ return self.value
290
+
291
+
292
+ class OpenPathType(Enum):
293
+ """
294
+ Path types resolved when running patkit subcommands (open, interact...).
295
+ """
296
+ MANIFEST = "manifest"
297
+ SCENARIO = "scenario"
298
+ SINGLE_DATA = "single_data"
299
+ DIRECTORY = "directory"
300
+
260
301
 
261
302
  # def patkit_suffix(
262
303
  # patkit_type: Union[Recording, Session, Modality]) -> str:
@@ -430,3 +471,49 @@ class ExerciseMode(ListablePrintableEnum, metaclass=ValueComparedEnumMeta):
430
471
  """
431
472
  ANSWER = "Answer"
432
473
  EXAMPLE = "Example"
474
+
475
+
476
+ class ExerciseScrambler(
477
+ ListablePrintableEnum, metaclass=ValueComparedEnumMeta
478
+ ):
479
+ """
480
+ Ways of scrambling boundaries for an Exercise.
481
+ """
482
+ EQUIDISTANT = "Equidistant"
483
+
484
+
485
+ class DefaultCanvasColors(str, Enum):
486
+ """
487
+ Default background colors for the Matplotlib figure canvas.
488
+
489
+ These represent the hardcoded default theme colors for different
490
+ annotator and exercise modes until config overrides are implemented.
491
+ """
492
+ ANNOTATOR_LIGHT = "white"
493
+ ANNOTATOR_DARK = "black"
494
+
495
+ EXAMPLE_LIGHT = "#e7eaff"
496
+ EXAMPLE_DARK = "#000212"
497
+
498
+ ANSWER_LIGHT = "#e6ffe9"
499
+ ANSWER_DARK = "#001202"
500
+
501
+ def __str__(self) -> str:
502
+ """
503
+ Ensure f-strings and print() output the string value.
504
+ """
505
+ return self.value
506
+
507
+
508
+ class DefaultCursorColors(str, Enum):
509
+ """
510
+ Default colors for GUI cursor and selection elements.
511
+ """
512
+ SELECTION = "deepskyblue"
513
+ PLAYBACK = "red"
514
+
515
+ def __str__(self) -> str:
516
+ """
517
+ Ensure f-strings and print() output the string value.
518
+ """
519
+ return self.value
@@ -43,7 +43,7 @@ from .data_structures import (
43
43
  Exercise, Answer, Manifest, Modality, Recording, Session
44
44
  )
45
45
  from .metadata_classes import (
46
- FileInformation,
46
+ AnswerMetadata, ExerciseMetadata, FileInformation,
47
47
  ModalityData, ModalityMetaData, PointAnnotations,
48
48
  RecordingMetaData, StatisticMetaData
49
49
  )
@@ -52,10 +52,10 @@ class AbstractDataObject(abc.ABC):
52
52
  Abstract base class for patkit data objects.
53
53
 
54
54
  Almost no class should directly inherit from this class. Exceptions are
55
- AbstractDataContainer and AbstractData. The latter is the abstract baseclass for
56
- Modality and Statistic and the former for all data base classes: Recording,
57
- Session, DataSet and any others that contain either DataContainers and/or
58
- AbstractDataContainers.
55
+ AbstractDataContainer and AbstractData. The latter is the abstract
56
+ baseclass for Modality and Statistic and the former for all data base
57
+ classes: Recording, Session, DataSet and any others that contain either
58
+ DataContainers and/or AbstractDataContainers.
59
59
  """
60
60
 
61
61
  def __init__(self,
@@ -116,7 +116,7 @@ class AbstractDataObject(abc.ABC):
116
116
  @property
117
117
  def file_info(self) -> FileInformation:
118
118
  """
119
- The paths and filenames of this AbstractDataObject as a FileInformation object.
119
+ The paths and filenames of this AbstractDataObject.
120
120
 
121
121
  NOTE: Regularly you should not need to access this directly. Instead,
122
122
  use the `[recorded|patkit]_path`, `[recorded|patkit]_data_file`, and
@@ -182,7 +182,7 @@ class AbstractDataObject(abc.ABC):
182
182
  Path to the recorded meta data file of this AbstractDataObject.
183
183
 
184
184
  This file will exist only for some recorded data. For example, wav
185
- files do not have a corresponding recorded meta data file.
185
+ files do not have a corresponding recorded meta data file.
186
186
 
187
187
  This file may also cover more than one recorded data file - usually a
188
188
  whole Session if not just a single recorded data file.
@@ -230,7 +230,7 @@ class AbstractDataObject(abc.ABC):
230
230
  """
231
231
  if not self._file_info.recorded_path:
232
232
  return None
233
- if not self.container is None:
233
+ if self.container is not None:
234
234
  return self.container.recorded_path / self._file_info.recorded_path
235
235
  return self._file_info.recorded_path
236
236
 
@@ -367,11 +367,11 @@ class AbstractDataObject(abc.ABC):
367
367
  Get meta data as a dict.
368
368
 
369
369
  This is a helper method for saving as nested text. Allows for rewriting
370
- any fields that need a simpler representation.
370
+ any fields that need a simpler representation.
371
371
 
372
372
  Subclasses should override this method if any of their fields require
373
373
  special handling such as derived Enums needing to be converted to plain
374
- text etc.
374
+ text etc.
375
375
 
376
376
  Returns
377
377
  -------
@@ -383,9 +383,9 @@ class AbstractDataObject(abc.ABC):
383
383
 
384
384
  class AbstractDataContainer(AbstractDataObject):
385
385
  """
386
- Abstract baseclass for Recording, Session, and DataSet.
386
+ Abstract baseclass for Recording, Session, and DataSet.
387
387
 
388
- This class collects behaviors that are shared by the data base classes i.e.
388
+ This class collects behaviors that are shared by the database classes i.e.
389
389
  classes which collect DataContainers and/or AbstractDataContainers.
390
390
  """
391
391
 
@@ -409,9 +409,9 @@ class AbstractDataContainer(AbstractDataObject):
409
409
  """
410
410
  Name of this instance.
411
411
 
412
- AbstractDataContainers get their names mainly from the file system. DataSets
413
- are named after the root directory name, Sessions for the session
414
- directories and Trials for the trial file names.
412
+ AbstractDataContainers get their names mainly from the file system.
413
+ DataSets are named after the root directory name, Sessions for the
414
+ session directories and Trials for the trial file names.
415
415
 
416
416
  Returns
417
417
  -------
@@ -456,7 +456,7 @@ class AbstractDataContainer(AbstractDataObject):
456
456
 
457
457
  class AbstractData(AbstractDataObject):
458
458
  """
459
- Abstract baseclass for Modality and Statistic.
459
+ Abstract baseclass for Modality and Statistic.
460
460
 
461
461
  This class collects behaviors shared by the classes that contain data:
462
462
  Modalities contain time varying data and Statistics contain time
@@ -519,7 +519,7 @@ class AbstractData(AbstractDataObject):
519
519
 
520
520
  class Statistic(AbstractData):
521
521
  """
522
- Abstract baseclass for statistics generated from members of a container.
522
+ Abstract baseclass for statistics generated from members of a container.
523
523
 
524
524
  Specifically Statistics are time independent data while Modalities are
525
525
  time-dependent data.
@@ -539,16 +539,17 @@ class Statistic(AbstractData):
539
539
  parsed_data: np.ndarray | None = None,
540
540
  ) -> None:
541
541
  """
542
- Build a Statistic.
542
+ Build a Statistic.
543
543
 
544
544
  Parameters
545
545
  ----------
546
546
  metadata : PatkitBaseModel
547
547
  Parameters used in calculating this Statistic.
548
548
  container : AbstractDataContainer
549
- The container of this Statistic. Usually this will be the object whose
550
- contents this Statistic was calculated on. By default, None, to
551
- facilitate mass generation and setting the container after wards.
549
+ The container of this Statistic. Usually this will be the object
550
+ whose contents this Statistic was calculated on. By default, None,
551
+ to facilitate mass generation and setting the container after
552
+ wards.
552
553
  file_info : FileInformation
553
554
  The patkit load path and names for this Statistic. Recorded path
554
555
  and names should usually be empty. Defaults to None, when the