Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add 'origin' argument to handle 'layers' attributes in Dezrann labels #48

Merged
merged 3 commits into from
Feb 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions src/ms3/dezrann.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@

import json
import os
from typing import Dict, List, TypedDict, Any, Union
from typing import Dict, List, TypedDict, Union, Tuple

from fractions import Fraction
import pandas as pd
Expand All @@ -120,8 +120,10 @@ class DezrannLabel(TypedDict):
duration: float
line: str #= "top.3" #Literal?
tag: str
layers: List[str]

class DezrannDict(TypedDict):
"""Represents one .dez file."""
labels: List[DezrannLabel]
meta: Dict

Expand Down Expand Up @@ -157,30 +159,49 @@ def transform_df(labels: pd.DataFrame,
transformed_df = pd.concat([quarterbeats.rename('quarterbeats'), labels.duration_qb.rename('duration'), labels[label_column].rename('label')], axis=1)
return transformed_df.to_dict(orient='records')

def make_dezrann_label(quarterbeats: float, duration: float, label: str) -> DezrannLabel:
return DezrannLabel(type="Harmony", start=quarterbeats, duration=duration, line="top.3", tag=label)
def make_dezrann_label(
quarterbeats: float, duration: float, label: str, origin: Union[str, Tuple[str]]) -> DezrannLabel:
if isinstance(origin, str):
layers = [origin]
else:
layers = list(origin)
return DezrannLabel(
type="Harmony",
start=quarterbeats,
duration=duration,
line="top.3",
tag=label,
layers=layers
)

def convert_dcml_list_to_dezrann_list(values_dict: List[DcmlLabel]) -> List[DezrannDict]:
def convert_dcml_list_to_dezrann_list(values_dict: List[DcmlLabel],
origin: Union[str, Tuple[str]] = "DCML") -> DezrannDict:
label_list = []
for e in values_dict:
label_list.append(
make_dezrann_label(
quarterbeats=e["quarterbeats"],
duration=e["duration"],
label=e["label"]
label=e["label"],
origin=origin
)
)
return DezrannDict(labels=label_list, meta={"layout": []})


def generate_dez(path_measures, path_labels, output_path="labels.dez"): # need paths for harmony.TSV + paths for measures.TSV
def generate_dez(path_measures: str,
path_labels: str,
output_path: str = "labels.dez",
origin: Union[str, Tuple[str]] = "DCML"):
"""
path_measures : :obj:`str`
Path to a TSV file as output by format_data().
path_labels : :obj:`str`
Path to a TSV file as output by format_data().
output_labels : :obj:`str`
Path to a TSV file as output by format_data().
origin : :obj:`list`
List of source(s) from which the labels originate. Defaults to ["DCML"].
"""
harmonies = pd.read_csv(
path_labels, sep='\t',
Expand All @@ -193,7 +214,7 @@ def generate_dez(path_measures, path_labels, output_path="labels.dez"): # need p
converters={'quarterbeats_all_endings': safe_frac}
)
dcml_labels = transform_df(labels=harmonies, measures=measures)
dezrann_content = convert_dcml_list_to_dezrann_list(dcml_labels)
dezrann_content = convert_dcml_list_to_dezrann_list(dcml_labels, origin=origin)

# Manual post-processing #TODO: improve these cases
# 1) Avoid NaN values in "duration" (happens in second endings)
Expand Down