partitura 1.3.0__py3-none-any.whl → 1.4.0__py3-none-any.whl

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 (41) hide show
  1. partitura/directions.py +3 -0
  2. partitura/display.py +0 -1
  3. partitura/io/__init__.py +41 -35
  4. partitura/io/exportmatch.py +52 -10
  5. partitura/io/exportmidi.py +37 -19
  6. partitura/io/exportmusicxml.py +6 -92
  7. partitura/io/exportparangonada.py +18 -19
  8. partitura/io/importkern.py +2 -4
  9. partitura/io/importmatch.py +121 -39
  10. partitura/io/importmei.py +161 -34
  11. partitura/io/importmidi.py +23 -14
  12. partitura/io/importmusic21.py +0 -1
  13. partitura/io/importmusicxml.py +48 -63
  14. partitura/io/importparangonada.py +0 -1
  15. partitura/io/matchfile_base.py +0 -21
  16. partitura/io/matchfile_utils.py +29 -17
  17. partitura/io/matchlines_v0.py +0 -22
  18. partitura/io/matchlines_v1.py +8 -42
  19. partitura/io/musescore.py +68 -41
  20. partitura/musicanalysis/__init__.py +1 -1
  21. partitura/musicanalysis/note_array_to_score.py +147 -92
  22. partitura/musicanalysis/note_features.py +66 -51
  23. partitura/musicanalysis/performance_codec.py +140 -96
  24. partitura/musicanalysis/performance_features.py +190 -129
  25. partitura/musicanalysis/pitch_spelling.py +0 -2
  26. partitura/musicanalysis/tonal_tension.py +0 -6
  27. partitura/musicanalysis/voice_separation.py +1 -22
  28. partitura/performance.py +178 -5
  29. partitura/score.py +154 -74
  30. partitura/utils/__init__.py +1 -1
  31. partitura/utils/generic.py +3 -7
  32. partitura/utils/misc.py +0 -1
  33. partitura/utils/music.py +108 -66
  34. partitura/utils/normalize.py +75 -35
  35. partitura/utils/synth.py +1 -7
  36. {partitura-1.3.0.dist-info → partitura-1.4.0.dist-info}/METADATA +2 -2
  37. partitura-1.4.0.dist-info/RECORD +51 -0
  38. {partitura-1.3.0.dist-info → partitura-1.4.0.dist-info}/WHEEL +1 -1
  39. partitura-1.3.0.dist-info/RECORD +0 -51
  40. {partitura-1.3.0.dist-info → partitura-1.4.0.dist-info}/LICENSE +0 -0
  41. {partitura-1.3.0.dist-info → partitura-1.4.0.dist-info}/top_level.txt +0 -0
@@ -24,14 +24,14 @@ __all__ = ["encode_performance", "decode_performance", "to_matched_score"]
24
24
  #### Full Codecs ####
25
25
 
26
26
 
27
- @deprecated_alias(part='score', ppart="performance")
27
+ @deprecated_alias(part="score", ppart="performance")
28
28
  def encode_performance(
29
29
  score: ScoreLike,
30
30
  performance: PerformanceLike,
31
31
  alignment: list,
32
32
  return_u_onset_idx=False,
33
33
  beat_normalization: str = "beat_period", # "beat_period_log", "beat_period_ratio", "beat_period_ratio_log", "beat_period_standardized"
34
- tempo_smooth: Union[str, Callable] = "average"
34
+ tempo_smooth: Union[str, Callable] = "average",
35
35
  ):
36
36
  """
37
37
  Encode expressive parameters from a matched performance
@@ -77,7 +77,7 @@ def encode_performance(
77
77
  performed_durations=m_score["p_duration"],
78
78
  return_u_onset_idx=True,
79
79
  beat_normalization=beat_normalization,
80
- tempo_smooth=tempo_smooth
80
+ tempo_smooth=tempo_smooth,
81
81
  )
82
82
 
83
83
  # Get dynamics-related parameters
@@ -93,7 +93,7 @@ def encode_performance(
93
93
  return parameters, snote_ids
94
94
 
95
95
 
96
- @deprecated_alias(part='score')
96
+ @deprecated_alias(part="score")
97
97
  def decode_performance(
98
98
  score: ScoreLike,
99
99
  performance_array: np.ndarray,
@@ -101,7 +101,7 @@ def decode_performance(
101
101
  part_id=None,
102
102
  part_name=None,
103
103
  return_alignment=False,
104
- beat_normalization: str = "beat_period", # "beat_period_log", "beat_period_ratio", "beat_period_ratio_log", "beat_period_standardized"
104
+ beat_normalization: str = "beat_period", # "beat_period_log", "beat_period_ratio", "beat_period_ratio_log", "beat_period_standardized"
105
105
  *args,
106
106
  **kwargs
107
107
  ) -> PerformedPart:
@@ -131,10 +131,10 @@ def decode_performance(
131
131
  snotes = score.note_array()
132
132
 
133
133
  if snote_ids is None:
134
- snote_ids = [n['id'] for n in snotes]
134
+ snote_ids = [n["id"] for n in snotes]
135
135
  snote_info = snotes
136
136
  else:
137
- snote_info = snotes[np.isin(snotes['id'], snote_ids)]
137
+ snote_info = snotes[np.isin(snotes["id"], snote_ids)]
138
138
 
139
139
  # sort
140
140
  sort_idx = np.lexsort((snote_info["pitch"], snote_info["onset_div"]))
@@ -147,7 +147,7 @@ def decode_performance(
147
147
 
148
148
  dynamics_params = performance_array["velocity"][sort_idx]
149
149
  if beat_normalization != "beat_period":
150
- norm_params = list(TEMPO_NORMALIZATION[beat_normalization]['param_names'])
150
+ norm_params = list(TEMPO_NORMALIZATION[beat_normalization]["param_names"])
151
151
  else:
152
152
  norm_params = []
153
153
  time_params = performance_array[
@@ -188,21 +188,25 @@ def decode_performance(
188
188
  alignment = []
189
189
  for snote, pnote in zip(snote_info, ppart.notes):
190
190
  alignment.append(
191
- dict(label="match", score_id=snote['id'], performance_id=pnote["id"])
191
+ dict(label="match", score_id=snote["id"], performance_id=pnote["id"])
192
192
  )
193
193
 
194
194
  return ppart, alignment
195
195
  else:
196
-
197
196
  return ppart
198
197
 
198
+
199
199
  #### Time and Articulation Codecs ####
200
200
 
201
- def decode_time(score_onsets,
202
- score_durations,
203
- parameters,
204
- normalization = "beat_period",
205
- *args, **kwargs):
201
+
202
+ def decode_time(
203
+ score_onsets,
204
+ score_durations,
205
+ parameters,
206
+ normalization="beat_period",
207
+ *args,
208
+ **kwargs
209
+ ):
206
210
  """
207
211
  Decode a performance into onsets and durations in seconds
208
212
  for each note in the score.
@@ -222,16 +226,29 @@ def decode_time(score_onsets,
222
226
  # reconstruct the time by the extra parameters, for testing the inversion.
223
227
  # In practice, always reconstruct the time by beat_period.
224
228
  if normalization != "beat_period":
225
- tempo_param_names = list(TEMPO_NORMALIZATION[normalization]['param_names'])
229
+ tempo_param_names = list(TEMPO_NORMALIZATION[normalization]["param_names"])
226
230
  time_param = np.array(
227
- [tuple(np.mean(rfn.structured_to_unstructured(parameters[tempo_param_names][uix]), axis=0),) for uix in unique_onset_idxs],
228
- dtype=[(tp, "f4") for tp in tempo_param_names]
231
+ [
232
+ tuple(
233
+ np.mean(
234
+ rfn.structured_to_unstructured(
235
+ parameters[tempo_param_names][uix]
236
+ ),
237
+ axis=0,
238
+ ),
239
+ )
240
+ for uix in unique_onset_idxs
241
+ ],
242
+ dtype=[(tp, "f4") for tp in tempo_param_names],
229
243
  )
230
- beat_period = TEMPO_NORMALIZATION[normalization]['rescale'](time_param)
244
+ beat_period = TEMPO_NORMALIZATION[normalization]["rescale"](time_param)
231
245
 
232
246
  else:
233
247
  time_param = np.array(
234
- [tuple([np.mean(parameters["beat_period"][uix])]) for uix in unique_onset_idxs],
248
+ [
249
+ tuple([np.mean(parameters["beat_period"][uix])])
250
+ for uix in unique_onset_idxs
251
+ ],
235
252
  dtype=[("beat_period", "f4")],
236
253
  )
237
254
  beat_period = time_param["beat_period"]
@@ -265,7 +282,6 @@ def encode_articulation(
265
282
  """
266
283
  articulation = np.zeros_like(score_durations)
267
284
  for idx, bp in zip(unique_onset_idxs, beat_period):
268
-
269
285
  sd = score_durations[idx]
270
286
  pd = performed_durations[idx]
271
287
 
@@ -296,8 +312,8 @@ def encode_tempo(
296
312
  score_durations,
297
313
  performed_durations,
298
314
  return_u_onset_idx: bool = False,
299
- beat_normalization: str = "beat_period", # "beat_period_log", "beat_period_ratio", "beat_period_ratio_log", "beat_period_standardized"
300
- tempo_smooth: Union[str, Callable] = "average" # "average" or "derivative"
315
+ beat_normalization: str = "beat_period", # "beat_period_log", "beat_period_ratio", "beat_period_ratio_log", "beat_period_standardized"
316
+ tempo_smooth: Union[str, Callable] = "average", # "average" or "derivative"
301
317
  ) -> np.ndarray:
302
318
  """
303
319
  Compute time-related performance parameters from a performance
@@ -348,8 +364,10 @@ def encode_tempo(
348
364
 
349
365
  # Compute tempo parameter and normalize
350
366
  if beat_normalization != "beat_period":
351
- tempo_params = np.array(TEMPO_NORMALIZATION[beat_normalization]['scale'](beat_period))
352
- tempo_param_names = list(TEMPO_NORMALIZATION[beat_normalization]['param_names'])
367
+ tempo_params = np.array(
368
+ TEMPO_NORMALIZATION[beat_normalization]["scale"](beat_period)
369
+ )
370
+ tempo_param_names = list(TEMPO_NORMALIZATION[beat_normalization]["param_names"])
353
371
 
354
372
  # Compute articulation parameter
355
373
  articulation_param = encode_articulation(
@@ -454,9 +472,7 @@ def tempo_by_average(
454
472
  eq_onsets = perf_info["u_onset"]
455
473
 
456
474
  # Monotonize times
457
- eq_onset_mt, unique_s_onsets_mt = monotonize_times(
458
- eq_onsets, x=unique_s_onsets
459
- )
475
+ eq_onset_mt, unique_s_onsets_mt = monotonize_times(eq_onsets, x=unique_s_onsets)
460
476
 
461
477
  # Estimate Beat Period
462
478
  perf_iois = np.diff(eq_onset_mt)
@@ -475,19 +491,26 @@ def tempo_by_average(
475
491
  input_onsets = unique_s_onsets[:-1]
476
492
 
477
493
  tempo_curve = tempo_fun(input_onsets)
478
-
479
- assert((tempo_curve >= 0).all())
494
+ if not (tempo_curve >= 0).all():
495
+ warnings.warn(
496
+ "The estimated tempo curve is not always positive. "
497
+ "This might be due to a bad alignment."
498
+ )
480
499
  if return_onset_idxs:
481
500
  return tempo_curve, input_onsets, unique_onset_idxs
482
501
  else:
483
502
  return tempo_curve, input_onsets
484
503
 
485
504
 
486
- def tempo_by_derivative(score_onsets, performed_onsets,
487
- score_durations, performed_durations,
488
- unique_onset_idxs=None,
489
- input_onsets=None,
490
- return_onset_idxs=False):
505
+ def tempo_by_derivative(
506
+ score_onsets,
507
+ performed_onsets,
508
+ score_durations,
509
+ performed_durations,
510
+ unique_onset_idxs=None,
511
+ input_onsets=None,
512
+ return_onset_idxs=False,
513
+ ):
491
514
  """
492
515
  Computes a tempo curve using the derivative of the average performed
493
516
  onset times of all notes belonging to the same score onset with respect
@@ -542,28 +565,32 @@ def tempo_by_derivative(score_onsets, performed_onsets,
542
565
  unique_onset_idxs = get_unique_onset_idxs((1e4 * score_onsets).astype(int))
543
566
 
544
567
  # Get score information
545
- score_info = get_unique_seq(onsets=score_onsets,
546
- offsets=score_onsets + score_durations,
547
- unique_onset_idxs=unique_onset_idxs,
548
- return_diff=False)
568
+ score_info = get_unique_seq(
569
+ onsets=score_onsets,
570
+ offsets=score_onsets + score_durations,
571
+ unique_onset_idxs=unique_onset_idxs,
572
+ return_diff=False,
573
+ )
549
574
  # Get performance information
550
- perf_info = get_unique_seq(onsets=performed_onsets,
551
- offsets=performed_onsets + performed_durations,
552
- unique_onset_idxs=unique_onset_idxs,
553
- return_diff=False)
575
+ perf_info = get_unique_seq(
576
+ onsets=performed_onsets,
577
+ offsets=performed_onsets + performed_durations,
578
+ unique_onset_idxs=unique_onset_idxs,
579
+ return_diff=False,
580
+ )
554
581
 
555
582
  # unique score onsets
556
- unique_s_onsets = score_info['u_onset']
583
+ unique_s_onsets = score_info["u_onset"]
557
584
  # equivalent onsets
558
- eq_onsets = perf_info['u_onset']
585
+ eq_onsets = perf_info["u_onset"]
559
586
 
560
587
  # Monotonize times
561
- eq_onset_mt, unique_s_onsets_mt = monotonize_times(eq_onsets,
562
- x=unique_s_onsets)
588
+ eq_onset_mt, unique_s_onsets_mt = monotonize_times(eq_onsets, x=unique_s_onsets)
563
589
  # Function that that interpolates the equivalent performed onsets
564
590
  # as a function of the score onset.
565
- onset_fun = interp1d(unique_s_onsets_mt, eq_onset_mt, kind='linear',
566
- fill_value='extrapolate')
591
+ onset_fun = interp1d(
592
+ unique_s_onsets_mt, eq_onset_mt, kind="linear", fill_value="extrapolate"
593
+ )
567
594
 
568
595
  if input_onsets is None:
569
596
  input_onsets = unique_s_onsets[:-1]
@@ -579,11 +606,13 @@ def tempo_by_derivative(score_onsets, performed_onsets,
579
606
  #### Alignment Processing ####
580
607
 
581
608
 
582
- @deprecated_alias(part='score', ppart="performance")
583
- def to_matched_score(score: ScoreLike,
584
- performance: PerformanceLike,
585
- alignment: list,
586
- include_score_markings=False):
609
+ @deprecated_alias(part="score", ppart="performance")
610
+ def to_matched_score(
611
+ score: ScoreLike,
612
+ performance: PerformanceLike,
613
+ alignment: list,
614
+ include_score_markings=False,
615
+ ):
587
616
  """
588
617
  Returns a mixed score-performance note array
589
618
  consisting of matched notes in the alignment.
@@ -607,13 +636,17 @@ def to_matched_score(score: ScoreLike,
607
636
 
608
637
  feature_functions = None
609
638
  if include_score_markings:
610
- feature_functions = ["loudness_direction_feature", "articulation_feature",
611
- "tempo_direction_feature", "slur_feature"]
639
+ feature_functions = [
640
+ "loudness_direction_feature",
641
+ "articulation_feature",
642
+ "tempo_direction_feature",
643
+ "slur_feature",
644
+ ]
612
645
 
613
646
  na = note_features.compute_note_array(score, feature_functions=feature_functions)
614
647
  p_na = performance.note_array()
615
- part_by_id = dict((n['id'], na[na['id'] == n['id']]) for n in na)
616
- ppart_by_id = dict((n['id'], p_na[p_na['id'] == n['id']]) for n in p_na)
648
+ part_by_id = dict((n["id"], na[na["id"] == n["id"]]) for n in na)
649
+ ppart_by_id = dict((n["id"], p_na[p_na["id"] == n["id"]]) for n in p_na)
617
650
 
618
651
  # pair matched score and performance notes
619
652
  note_pairs = [
@@ -623,21 +656,23 @@ def to_matched_score(score: ScoreLike,
623
656
  ]
624
657
  ms = []
625
658
  # sort according to onset (primary) and pitch (secondary)
626
- pitch_onset = [(sn['pitch'].item(), sn['onset_div'].item()) for sn, _ in note_pairs]
659
+ pitch_onset = [(sn["pitch"].item(), sn["onset_div"].item()) for sn, _ in note_pairs]
627
660
  sort_order = np.lexsort(list(zip(*pitch_onset)))
628
661
  snote_ids = []
629
662
  for i in sort_order:
630
663
  sn, n = note_pairs[int(i)]
631
- sn_on, sn_off = [sn['onset_beat'], sn['onset_beat'] + sn['duration_beat']]
664
+ sn_on, sn_off = [sn["onset_beat"], sn["onset_beat"] + sn["duration_beat"]]
632
665
  sn_dur = sn_off - sn_on
633
666
  # hack for notes with negative durations
634
667
  n_dur = max(n["duration_sec"], 60 / 200 * 0.25)
635
- pair_info = (sn_on, sn_dur, sn['pitch'], n["onset_sec"], n_dur, n["velocity"])
668
+ pair_info = (sn_on, sn_dur, sn["pitch"], n["onset_sec"], n_dur, n["velocity"])
636
669
  if include_score_markings:
637
- pair_info += (sn['voice'].item(), )
638
- pair_info += tuple([sn[field].item() for field in sn.dtype.names if "feature" in field])
670
+ pair_info += (sn["voice"].item(),)
671
+ pair_info += tuple(
672
+ [sn[field].item() for field in sn.dtype.names if "feature" in field]
673
+ )
639
674
  ms.append(pair_info)
640
- snote_ids.append(sn['id'].item())
675
+ snote_ids.append(sn["id"].item())
641
676
 
642
677
  fields = [
643
678
  ("onset", "f4"),
@@ -649,7 +684,11 @@ def to_matched_score(score: ScoreLike,
649
684
  ]
650
685
  if include_score_markings:
651
686
  fields += [("voice", "i4")]
652
- fields += [(field, sn.dtype.fields[field][0]) for field in sn.dtype.fields if "feature" in field]
687
+ fields += [
688
+ (field, sn.dtype.fields[field][0])
689
+ for field in sn.dtype.fields
690
+ if "feature" in field
691
+ ]
653
692
 
654
693
  return np.array(ms, dtype=fields), snote_ids
655
694
 
@@ -774,7 +813,6 @@ def get_matched_notes(spart_note_array, ppart_note_array, alignment):
774
813
  for al in alignment:
775
814
  # Get only matched notes (i.e., ignore inserted or deleted notes)
776
815
  if al["label"] == "match":
777
-
778
816
  # if ppart_note_array['id'].dtype != type(al['performance_id']):
779
817
  if not isinstance(ppart_note_array["id"], type(al["performance_id"])):
780
818
  p_id = str(al["performance_id"])
@@ -799,12 +837,15 @@ def get_unique_seq(onsets, offsets, unique_onset_idxs=None, return_diff=False):
799
837
  """
800
838
  Get unique onsets of a sequence of notes
801
839
  """
802
- eps = np.finfo(float).eps
803
840
 
804
841
  first_time = np.min(onsets)
805
842
 
806
843
  # ensure last score time is later than last onset
807
- last_time = max(np.max(onsets) + eps, np.max(offsets))
844
+ if np.max(onsets) == np.max(offsets):
845
+ # last note without duration (grace note)
846
+ last_time = np.max(onsets) + 1
847
+ else:
848
+ last_time = np.max(offsets)
808
849
 
809
850
  total_dur = last_time - first_time
810
851
 
@@ -868,13 +909,12 @@ def get_unique_onset_idxs(
868
909
 
869
910
  def notewise_to_onsetwise(notewise_inputs, unique_onset_idxs):
870
911
  """Agregate basis functions per onset"""
871
-
912
+
872
913
  if notewise_inputs.ndim == 1:
873
914
  shape = len(unique_onset_idxs)
874
915
  else:
875
916
  shape = (len(unique_onset_idxs),) + notewise_inputs.shape[1:]
876
917
  onsetwise_inputs = np.zeros(shape, dtype=notewise_inputs.dtype)
877
-
878
918
 
879
919
  for i, uix in enumerate(unique_onset_idxs):
880
920
  try:
@@ -893,7 +933,7 @@ def onsetwise_to_notewise(onsetwise_input, unique_onset_idxs):
893
933
  else:
894
934
  shape = (n_notes,) + onsetwise_input.shape[1:]
895
935
  notewise_inputs = np.zeros(shape, dtype=onsetwise_input.dtype)
896
-
936
+
897
937
  for i, uix in enumerate(unique_onset_idxs):
898
938
  notewise_inputs[uix] = onsetwise_input[[i]]
899
939
  return notewise_inputs
@@ -907,7 +947,7 @@ def bp_scale(beat_period):
907
947
 
908
948
 
909
949
  def bp_rescale(tempo_params):
910
- return tempo_params['beat_period']
950
+ return tempo_params["beat_period"]
911
951
 
912
952
 
913
953
  def beat_period_log_scale(beat_period):
@@ -915,7 +955,7 @@ def beat_period_log_scale(beat_period):
915
955
 
916
956
 
917
957
  def beat_period_log_rescale(tempo_params):
918
- return 2 ** tempo_params['beat_period_log']
958
+ return 2 ** tempo_params["beat_period_log"]
919
959
 
920
960
 
921
961
  def beat_period_standardized_scale(beat_period):
@@ -926,8 +966,10 @@ def beat_period_standardized_scale(beat_period):
926
966
 
927
967
 
928
968
  def beat_period_standardized_rescale(tempo_params):
929
- return (tempo_params['beat_period_standardized'] * tempo_params['beat_period_std']
930
- + tempo_params['beat_period_mean'])
969
+ return (
970
+ tempo_params["beat_period_standardized"] * tempo_params["beat_period_std"]
971
+ + tempo_params["beat_period_mean"]
972
+ )
931
973
 
932
974
 
933
975
  def beat_period_ratio_scale(beat_period):
@@ -937,7 +979,7 @@ def beat_period_ratio_scale(beat_period):
937
979
 
938
980
 
939
981
  def beat_period_ratio_rescale(tempo_params):
940
- return tempo_params['beat_period_ratio'] * tempo_params['beat_period_mean']
982
+ return tempo_params["beat_period_ratio"] * tempo_params["beat_period_mean"]
941
983
 
942
984
 
943
985
  def beat_period_ratio_log_scale(beat_period):
@@ -946,27 +988,29 @@ def beat_period_ratio_log_scale(beat_period):
946
988
 
947
989
 
948
990
  def beat_period_ratio_log_rescale(tempo_params):
949
- return (2 ** tempo_params['beat_period_ratio_log'] * tempo_params['beat_period_mean'])
991
+ return 2 ** tempo_params["beat_period_ratio_log"] * tempo_params["beat_period_mean"]
950
992
 
951
993
 
952
994
  TEMPO_NORMALIZATION = dict(
953
- beat_period=dict(scale=bp_scale,
954
- rescale=bp_rescale,
955
- param_names=('beat_period',)),
956
- beat_period_log=dict(scale=beat_period_log_scale,
957
- rescale=beat_period_log_rescale,
958
- param_names=('beat_period_log',)),
959
- beat_period_ratio=dict(scale=beat_period_ratio_scale,
960
- rescale=beat_period_ratio_rescale,
961
- param_names=('beat_period_ratio',
962
- 'beat_period_mean')),
963
- beat_period_ratio_log=dict(scale=beat_period_ratio_log_scale,
964
- rescale=beat_period_ratio_log_rescale,
965
- param_names=('beat_period_ratio_log',
966
- 'beat_period_mean')),
967
- beat_period_standardized=dict(scale=beat_period_standardized_scale,
968
- rescale=beat_period_standardized_rescale,
969
- param_names=('beat_period_standardized',
970
- 'beat_period_mean', 'beat_period_std'))
995
+ beat_period=dict(scale=bp_scale, rescale=bp_rescale, param_names=("beat_period",)),
996
+ beat_period_log=dict(
997
+ scale=beat_period_log_scale,
998
+ rescale=beat_period_log_rescale,
999
+ param_names=("beat_period_log",),
1000
+ ),
1001
+ beat_period_ratio=dict(
1002
+ scale=beat_period_ratio_scale,
1003
+ rescale=beat_period_ratio_rescale,
1004
+ param_names=("beat_period_ratio", "beat_period_mean"),
1005
+ ),
1006
+ beat_period_ratio_log=dict(
1007
+ scale=beat_period_ratio_log_scale,
1008
+ rescale=beat_period_ratio_log_rescale,
1009
+ param_names=("beat_period_ratio_log", "beat_period_mean"),
1010
+ ),
1011
+ beat_period_standardized=dict(
1012
+ scale=beat_period_standardized_scale,
1013
+ rescale=beat_period_standardized_rescale,
1014
+ param_names=("beat_period_standardized", "beat_period_mean", "beat_period_std"),
1015
+ ),
971
1016
  )
972
-