xarray-behave 0.35.4__tar.gz → 0.35.7__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 (57) hide show
  1. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/PKG-INFO +1 -1
  2. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/__init__.py +1 -1
  3. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/annot.py +16 -1
  4. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/app.py +29 -13
  5. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/das_predict.yaml +22 -1
  6. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/utils.py +1 -2
  7. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/xarray_behave.py +17 -13
  8. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/.github/workflows/publish.yaml +0 -0
  9. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/.gitignore +0 -0
  10. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/LICENSE +0 -0
  11. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/README.md +0 -0
  12. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/build_env.yml +0 -0
  13. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/conda/xarray-behave/bld.bat +0 -0
  14. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/conda/xarray-behave/build.sh +0 -0
  15. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/conda/xarray-behave/conda_build_config.yaml +0 -0
  16. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/conda/xarray-behave/meta.yaml +0 -0
  17. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/condarc.yml +0 -0
  18. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/doc/demo.ipynb +0 -0
  19. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/doc/demo_behavioral_features.ipynb +0 -0
  20. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/doc/demo_behavioral_features_large_group.ipynb +0 -0
  21. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/doc/ncb.mplstyle +0 -0
  22. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/pyproject.toml +0 -0
  23. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/setup.py +0 -0
  24. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/event_utils.py +0 -0
  25. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/__init__.py +0 -0
  26. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/audio_player.py +0 -0
  27. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/das.py +0 -0
  28. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/formbuilder.py +0 -0
  29. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/das_make.yaml +0 -0
  30. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/das_train.yaml +0 -0
  31. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/envelope_computation.yaml +0 -0
  32. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/export_for_das.yaml +0 -0
  33. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/from_dir.yaml +0 -0
  34. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/from_file.yaml +0 -0
  35. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/from_zarr.yaml +0 -0
  36. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/forms/spec_freq.yaml +0 -0
  37. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/icon.png +0 -0
  38. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/table.py +0 -0
  39. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/view_dialog.py +0 -0
  40. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/views.py +0 -0
  41. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/gui/widgets.py +0 -0
  42. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/__init__.py +0 -0
  43. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/annotations.py +0 -0
  44. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/annotations_manual.py +0 -0
  45. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/audio.py +0 -0
  46. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/balltracks.py +0 -0
  47. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/movieparams.py +0 -0
  48. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/poses.py +0 -0
  49. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/timestamps.py +0 -0
  50. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/io/tracks.py +0 -0
  51. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/loaders.py +0 -0
  52. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/src/xarray_behave/metrics.py +0 -0
  53. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/tests/test_annot.py +0 -0
  54. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/tests/test_assemble.py +0 -0
  55. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/tests/test_assemble_metrics.py +0 -0
  56. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/tests/test_imports.py +0 -0
  57. {xarray-behave-0.35.4 → xarray-behave-0.35.7}/tests/test_io.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xarray-behave
3
- Version: 0.35.4
3
+ Version: 0.35.7
4
4
  Summary: xarray tools for behavioral data.
5
5
  Author-email: Jan Clemens <clemensjan@googlemail.com>
6
6
  Requires-Python: >3.6
@@ -1,6 +1,6 @@
1
1
  """xarray tools for behavioral data."""
2
2
 
3
- __version__ = "0.35.4"
3
+ __version__ = "0.35.7"
4
4
 
5
5
  from .xarray_behave import assemble, assemble_metrics, load, save
6
6
  import os
@@ -87,7 +87,7 @@ class Events(UserDict):
87
87
  ):
88
88
  if possible_event_names is None:
89
89
  possible_event_names = []
90
- unique_names = list(set(names))
90
+ unique_names = list(np.unique(names)) # use `np.unique` instead of `set` to have reproducible order of names for now
91
91
  unique_names.extend(possible_event_names)
92
92
  dct = {name: [] for name in unique_names}
93
93
 
@@ -548,6 +548,18 @@ class Events(UserDict):
548
548
  self[name] = np.delete(self[name], indices, axis=0)
549
549
  return indices
550
550
 
551
+ def sort(self, names: Optional[List[str]] = None):
552
+ """Sort annotations by start time.
553
+
554
+ Args:
555
+ names (Optional[List[str]], optional): _description_. Defaults to None.
556
+ """
557
+ if names is None:
558
+ names = self.names
559
+
560
+ for name in names:
561
+ self[name] = self[name][np.argsort(self[name][:, 0]), :]
562
+
551
563
  def find_next(self, t: float, names: Optional[List[str]] = None):
552
564
  """Find event starting after `t` of type in names.
553
565
 
@@ -564,7 +576,9 @@ class Events(UserDict):
564
576
  names = self.names
565
577
 
566
578
  nxt = []
579
+
567
580
  for name in names:
581
+ self.sort([name])
568
582
  cmp = self[name][:, 0] > t
569
583
  if np.any(cmp):
570
584
  nxt.append(self[name][np.argmax(cmp), 0])
@@ -588,6 +602,7 @@ class Events(UserDict):
588
602
 
589
603
  nxt = []
590
604
  for name in names:
605
+ self.sort([name])
591
606
  cmp = self[name][:, 1] < t
592
607
  if np.any(cmp):
593
608
  nxt.append(self[name][np.argmin(cmp) - 1, 0])
@@ -674,6 +674,10 @@ class MainWindow(QtWidgets.QMainWindow):
674
674
  if form_data["segment_minlen"] is None:
675
675
  form_data["segment_minlen"] = 0
676
676
 
677
+ if form_data["filter_song"] == "no":
678
+ form_data["bandpass_low_freq"] = None
679
+ form_data["bandpass_up_freq"] = None
680
+
677
681
  if form_data["file"] != "Current file":
678
682
  if form_data["folder"] != " ":
679
683
  file_path = form_data["folder"]
@@ -696,6 +700,9 @@ class MainWindow(QtWidgets.QMainWindow):
696
700
  segment_thres=form_data["event_thres"],
697
701
  segment_fillgap=form_data["segment_fillgap"],
698
702
  segment_minlen=form_data["segment_minlen"],
703
+ bandpass_low_freq=form_data["bandpass_low_freq"],
704
+ bandpass_up_freq=form_data["bandpass_up_freq"],
705
+ resample=form_data["resample"],
699
706
  )
700
707
  return
701
708
  elif hasattr(self, "ds") and form_data["file"] == "Current file":
@@ -721,10 +728,10 @@ class MainWindow(QtWidgets.QMainWindow):
721
728
  # select batch size so that at least 10 batches are run
722
729
  # minimizes loss of annotations from batch size "quantization" errors
723
730
  batch_size = 32
724
- nb_batches = lambda batch_size: int(
731
+ nb_batches = int(
725
732
  np.floor((audio.shape[0] - ((batch_size - 1) + params["nb_hist"])) / (params["stride"] * (batch_size)))
726
733
  )
727
- while nb_batches(batch_size) < 10 and batch_size > 1:
734
+ while nb_batches < 10 and batch_size > 1:
728
735
  batch_size -= 1
729
736
 
730
737
  logger.info(" Running inference on audio.")
@@ -733,10 +740,13 @@ class MainWindow(QtWidgets.QMainWindow):
733
740
  fs_model = params["samplerate_x_Hz"]
734
741
  fs_audio = self.ds.song_raw.attrs["sampling_rate_Hz"]
735
742
 
736
- if form_data["resample_audio"] and fs_audio and fs_audio != fs_model:
743
+ if form_data["resample"] and fs_audio and fs_audio != fs_model:
737
744
  logger.info(f" Resampling. Audio rate is {fs_audio}Hz but model was trained on data with {fs_model}Hz.")
738
745
  audio = das.utils.resample(audio, fs_audio, fs_model)
739
746
 
747
+ import rich
748
+
749
+ rich.print(form_data)
740
750
  events, segments, _, _ = das.predict.predict(
741
751
  audio,
742
752
  model_path,
@@ -749,6 +759,10 @@ class MainWindow(QtWidgets.QMainWindow):
749
759
  segment_thres=form_data["event_thres"],
750
760
  segment_fillgap=form_data["segment_fillgap"],
751
761
  segment_minlen=form_data["segment_minlen"],
762
+ bandpass_low_freq=form_data["bandpass_low_freq"],
763
+ bandpass_up_freq=form_data["bandpass_up_freq"],
764
+ resample=form_data["resample"],
765
+ fs_audio=fs_audio,
752
766
  )
753
767
 
754
768
  # Process detected song
@@ -2070,24 +2084,26 @@ class PSV(MainWindow):
2070
2084
  self.update_frame()
2071
2085
 
2072
2086
  def set_prev_cuepoint(self, qt_keycode):
2073
- if self.edit_only_current_events: # of the currently active type
2074
- names = [self.current_event_name]
2075
- else: # of any type
2076
- names = self.event_times.names
2077
-
2087
+ # if self.edit_only_current_events: # of the currently active type
2088
+ # names = [self.current_event_name]
2089
+ # else: # of any type
2090
+ # names = self.event_times.names
2091
+ names = [self.current_event_name]
2078
2092
  t = (self.t0 - 1) / self.fs_song
2079
2093
  nxt = self.event_times.find_prev(t, names)
2094
+
2080
2095
  if nxt is not None:
2081
2096
  self.t0 = nxt * self.fs_song
2082
2097
 
2083
2098
  def set_next_cuepoint(self, qt_keycode):
2084
- if self.edit_only_current_events: # of the currently active type
2085
- names = [self.current_event_name]
2086
- else: # of any type
2087
- names = self.event_times.names
2088
-
2099
+ # if self.edit_only_current_events: # of the currently active type
2100
+ # names = [self.current_event_name]
2101
+ # else: # of any type
2102
+ # names = self.event_times.names
2103
+ names = [self.current_event_name]
2089
2104
  t = (self.t0 + 1) / self.fs_song
2090
2105
  nxt = self.event_times.find_next(t, names)
2106
+
2091
2107
  if nxt is not None:
2092
2108
  self.t0 = nxt * self.fs_song
2093
2109
 
@@ -65,11 +65,32 @@ main:
65
65
  default: True
66
66
  help: Appends '_proposals' to song name. Individual proposals can be corrected and approved.
67
67
 
68
- - name: resample_audio
68
+ - name: resample
69
69
  label: Resample audio to rate used for training
70
70
  type: bool
71
71
  default: True
72
72
 
73
+ - name: filter_song
74
+ label: Bandpass filter audio
75
+ type: stacked
76
+ default: "no"
77
+ options: "no,yes"
78
+
79
+ "no":
80
+
81
+ "yes":
82
+ - name: bandpass_low_freq
83
+ label: Lower cutoff
84
+ type: double
85
+ default: 50.0
86
+ range: 0.0, 1000000.0
87
+
88
+ - name: bandpass_up_freq
89
+ label: Upper cutoff
90
+ type: double
91
+ default: 10000.0
92
+ range: 0.0, 1000000.0
93
+
73
94
  - type: text
74
95
  text: '<b>Event detection</b>'
75
96
 
@@ -115,8 +115,7 @@ class FastImageWidget(pg.GraphicsLayoutWidget):
115
115
  image_format ([type], optional): [description]. Defaults to QtGui.QImage.Format_RGB888.
116
116
  auto_scale (bool, optional): [description]. Defaults to False.
117
117
  """
118
- qimg = QtGui.QImage(image, image.shape[1], image.shape[0], image_format)
119
- # qimg = QtGui.QImage(image.ctypes.data, image.shape[1], image.shape[0], image_format)
118
+ qimg = QtGui.QImage(image, image.shape[1], image.shape[0], 3 * image.shape[1], image_format)
120
119
 
121
120
  qpix = QtGui.QPixmap(qimg)
122
121
  self.pixmapItem.setPixmap(qpix)
@@ -177,6 +177,7 @@ def assemble(
177
177
  ss_ball, last_sample_number_ball, sampling_rate_ball = ld.load_times(filepath_timestamps_ball, filepath_daq)
178
178
 
179
179
  filepath_timestamps_movie = Path(root, res_path, datename, f"{datename}_movieframes.csv")
180
+ ss_movie = None
180
181
  if os.path.exists(filepath_daq) and os.path.exists(filepath_timestamps_movie):
181
182
  ss_movie, last_sample_number_movie, sampling_rate_movie = ld.load_movietimes(filepath_timestamps_movie, filepath_daq)
182
183
 
@@ -284,20 +285,23 @@ def assemble(
284
285
  with_movieparams = False
285
286
  if include_movieparams:
286
287
  logger.info("Loading movie params:")
287
- movieparams_loader = io.get_loader(kind="movieparams", basename=os.path.join(root, dat_path, datename, datename))
288
- if movieparams_loader:
289
- try:
290
- xr_movieparams = movieparams_loader.make(movieparams_loader.path)
291
- xr_movieparams = add_time(xr_movieparams, ss_movie, dim="frame_number_movie", suffix="_movie")
292
-
293
- logger.info(f" {movieparams_loader.path} loaded.")
294
- with_movieparams = True
295
- except Exception as e:
296
- logger.info(f" Loading {movieparams_loader.path} failed.")
297
- logger.exception(e)
288
+ if ss_movie is None:
289
+ logger.warning(" Failed loading movie params - no ss_movie")
298
290
  else:
299
- logger.info(" Found no movie params data.")
300
- logger.info("Done.")
291
+ movieparams_loader = io.get_loader(kind="movieparams", basename=os.path.join(root, dat_path, datename, datename))
292
+ if movieparams_loader:
293
+ try:
294
+ xr_movieparams = movieparams_loader.make(movieparams_loader.path)
295
+ xr_movieparams = add_time(xr_movieparams, ss_movie, dim="frame_number_movie", suffix="_movie")
296
+
297
+ logger.info(f" {movieparams_loader.path} loaded.")
298
+ with_movieparams = True
299
+ except Exception as e:
300
+ logger.info(f" Loading {movieparams_loader.path} failed.")
301
+ logger.exception(e)
302
+ else:
303
+ logger.warning(" Found no movie params data.")
304
+ logger.info("Done.")
301
305
 
302
306
  # Init empty and event data
303
307
  auto_event_seconds: Dict[str, Any] = {}
File without changes
File without changes
File without changes