search¶
Search algorithms.
-
class
decitala.search.
Extraction
(fragment: decitala.fragment.GeneralFragment, onset_range: tuple, retrograde: bool, factor: float, difference: float, mod_hierarchy_val: int, pitch_content: list, is_spanned_by_slur: bool, slur_count: int, slur_start_end_count: int, id_: int, contiguous_summation: bool = False)[source]¶ Bases:
object
-
decitala.search.
frame_to_ql_array
(frame)[source]¶ - Parameters
frame (list) – Frame of data from
get_object_indices
.- Returns
A numpy array holding the associated quarter length of a given window.
- Return type
numpy.array
>>> from music21 import note >>> my_frame = [ ... (note.Note("B-", quarterLength=0.125), (4.125, 4.25)), ... (note.Note("A", quarterLength=0.25), (4.25, 4.5)), ... (note.Note("B", quarterLength=0.125), (4.5, 4.625)), ... (note.Note("B-", quarterLength=0.125), (4.625, 4.75)), ... (note.Note("A", quarterLength=0.25), (4.75, 5.0)), ... (note.Note("G", quarterLength=0.25), (5.0, 5.25)), ... (note.Note("G", quarterLength=0.25), (5.25, 5.5)), ... ] >>> frame_to_ql_array(my_frame) array([0.125, 0.25 , 0.125, 0.125, 0.25 , 0.25 , 0.25 ])
-
decitala.search.
frame_to_midi
(frame, ignore_graces=True)[source]¶ - Parameters
frame (list) – Frame of data from
get_object_indices
.- Returns
A numpy array holding the pitches within the frame.
- Return type
numpy.array
>>> from music21 import note >>> my_frame = [ ... (note.Note("B-", quarterLength=0.125), (4.125, 4.25)), ... (note.Note("A", quarterLength=0.25), (4.25, 4.5)), ... (note.Note("B", quarterLength=0.125), (4.5, 4.625)), ... (note.Note("B-", quarterLength=0.125), (4.625, 4.75)), ... (note.Note("A", quarterLength=0.25), (4.75, 5.0)), ... (note.Note("G", quarterLength=0.25), (5.0, 5.25)), ... (note.Note("G", quarterLength=0.25), (5.25, 5.5)), ... ] >>> frame_to_midi(my_frame) [(70,), (69,), (71,), (70,), (69,), (67,), (67,)]
-
decitala.search.
frame_is_spanned_by_slur
(frame)[source]¶ - Parameters
frame (list) – frame from
get_object_indices
.- Returns
whether or not the frame is spanned by a music21.spanner.Slur object.
- Return type
bool
-
decitala.search.
frame_slur_count
(frame, allow_overlap=False)[source]¶ - Parameters
frame (list) – frame from
get_object_indices
.allow_overlap (bool) – whether to allow overlaps in the appearing slurs. If
False
, all the appearing slurs must start and end within the frame’s boundaries.
- Returns
The number of slurs in a frame.
- Return type
int
-
decitala.search.
frame_slur_start_end_count
(frame)[source]¶ Don’t love this, but let’s see if it works:
Returns 0 if neither the first nor last onset ends with a slur. Returns 1 if first or last onset ends with a slur. Returns 2 if the first and last onset ends with a slur(i.e. frame_is_spanned_by_slur=True).
-
decitala.search.
rolling_hash_search
(filepath, part_num, table, windows=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], allow_subdivision=False, allow_contiguous_summation=False)[source]¶ Function for searching a score for rhythmic fragments and modifications of rhythmic fragments. This function is faster and simpler than
decitala.search.rolling_tree_search()
.- Parameters
filepath (str) – Path to file to be searched.
part_num (int) – Part in the file to be searched (0-indexed).
table (decitala.hash_table.FragmentHashTable) – A
decitala.hash_table.FragmentHashTable
# noqa object or one of its subclasses.windows (list) – The allowed window sizes for search. Default is all integers in range 2-19.
allow_subdivision (bool) – Whether to check for subdivisions of a frame in the search.
-
decitala.search.
path_finder
(filepath, part_num, table, windows=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], allow_subdivision=False, allow_contiguous_summation=False, algorithm='dijkstra', cost_function_class=<decitala.path_finding.path_finding_utils.CostFunction3D object>, split_dict=None, slur_constraint=False, enforce_earliest_start=False, save_filepath=None, verbose=False)[source]¶ This function combines a number of tools for effectively finding a path of fragments through a provided composition and part number. It first runs
decitala.search.rolling_hash_search
to extract all fragments from the provided table and then runs the Floyd-Warshall algorithm to get the best path.- Parameters
filepath (str) – Path to file to be searched.
part_num (int) – Part in the file to be searched (0-indexed).
table (decitala.hash_table.FragmentHashTable) – A
decitala.hash_table.FragmentHashTable
# noqa object or one of its subclasses.windows (list) – The allowed window sizes for search. Default is all integers in range 2-19.
allow_subdivision (bool) – Whether to check for subdivisions of a frame in the search.
algorithm (str) – Path-finding algorithm used. Options are
"floyd_warshall"
and"dijkstra"
. Default is"dijkstra"
.slur_constraint (bool) – Whether to force slurred fragments to appear in the final path. Only possible if algorithm=”floyd-warshall”.
save_filepath (str) – An optional path to a JSON file for saving search results. This file can then be loaded with the
decitala.utils.loader()
.verbose (bool) – Whether to log messages. Default is
False
.
-
decitala.search.
rolling_search_on_array
(ql_array, table, windows=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18])[source]¶ A very light function for rhythmic search on an array. This is primarily useful for quick checks in a score. It does not support all possible modification types, etc…
- Parameters
ql_array (numpy.array) – A quarter length array.
table (decitala.hash_table.FragmentHashTable) – A
decitala.hash_table.FragmentHashTable
# noqa object or one of its subclasses.windows (list) – The allowed window sizes for search. Default is all integers in range 2-19.
- Returns
A list holding fragments in the array that were detected in the table.
- Return type
list
>>> ght = FragmentHashTable( ... datasets=["greek_foot"] ... ) >>> ght.load() >>> example_fragment = np.array([0.25, 0.5, 0.25, 0.5]) >>> for x in rolling_search_on_array(ql_array=example_fragment, table=ght): ... print(x["fragment"]) <fragment.GreekFoot Iamb> <fragment.GreekFoot Trochee> <fragment.GreekFoot Iamb> <fragment.GreekFoot Amphibrach> <fragment.GreekFoot Amphimacer> <fragment.GreekFoot Diiamb>
-
decitala.search.
get_by_ql_array
(ql_array, ratio_tree=None, difference_tree=None, allowed_modifications=['r', 'rr', 'd', 'rd', 'sr', 'rsr'], allow_unnamed=False)[source]¶ Searches a given ratio and/or difference tree for a given fragment. Allows grace notes.
- Parameters
ql_array (numpy.array) – fragment to be searched.
ratio_tree (FragmentTree) – tree storing ratio representations.
difference_tree (FragmentTree) – tree storing difference representations.
allowed_modifications (list) – possible ways for a fragment to be modified. Current possibilities are
r
,rr
,d
,rd
,sr
, andrsr
. NOTE: the order ofallowed_modifications
is the order of the search.allow_unnamed (bool) – whether or not to allow the retrieval of unnamed paths. The default is
False
.
>>> from decitala.trees import FragmentTree >>> fragment = np.array([3.0, 1.5, 1.5, 3.0]) >>> ratio_tree = FragmentTree.from_frag_type(frag_type='greek_foot', rep_type='ratio') >>> difference_tree = FragmentTree.from_frag_type(frag_type='greek_foot', rep_type='difference') >>> allowed_modifications = ["r", "rr"] >>> get_by_ql_array(fragment, ratio_tree, difference_tree, allowed_modifications) (<fragment.GreekFoot Choriamb>, ('r', 1.5))
-
decitala.search.
rolling_tree_search
(filepath, part_num, ratio_tree=None, difference_tree=None, allowed_modifications=['r', 'rr', 'd', 'rd', 'sr', 'rsr'], try_contiguous_summation=False, windows=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], allow_unnamed=False, logger=None)[source]¶ Rolling rhythmic search on a music21-readable file on a given part. For search types, see documentation for
get_by_ql_array()
. The default window lengths are the lengths of fragments in the decitala dataset.- Parameters
filepath (str) – path to file to be searched.
part_num (int) – part in the file to be searched (0-indexed).
ratio_tree (FragmentTree) – tree storing ratio representations.
difference_tree (FragmentTree) – tree storing difference representations.
allowed_modifications (list) – see
get_by_ql_array
.try_contiguous_summation (bool) – ties together all elements of equal pitch and duration and searches. See
contiguous_summation
.windows (list) – possible lengths of the search frames.
allow_unnamed (bool) – whether or not to include unnamed fragments (in the fragment tree(s)) in the return.
logger (bool) – logger object (see
get_logger
).
- Returns
list holding dictionaries, each of which holds fragment, modifiation, onset-range, and spanning data.
- Return type
list
>>> from decitala.trees import FragmentTree >>> ratio_tree = FragmentTree.from_frag_type(frag_type='greek_foot', rep_type='ratio') >>> difference_tree = FragmentTree.from_frag_type(frag_type='greek_foot', rep_type='difference') # noqa >>> ex = "./tests/static/Shuffled_Transcription_2.xml" >>> for tala_data in rolling_tree_search(ex, 0, ratio_tree, difference_tree, allowed_modifications=["r"])[0:5]: ... print(tala_data) {'fragment': <fragment.GreekFoot Trochee>, 'mod': ('r', 0.125), 'onset_range': (0.0, 0.375), 'is_spanned_by_slur': False, 'pitch_content': [(72,), (87,)], 'id': 1} {'fragment': <fragment.GreekFoot Dactyl>, 'mod': ('r', 0.125), 'onset_range': (0.0, 0.5), 'is_spanned_by_slur': False, 'pitch_content': [(72,), (87,), (79,)], 'id': 39} {'fragment': <fragment.GreekFoot Spondee>, 'mod': ('r', 0.0625), 'onset_range': (0.25, 0.5), 'is_spanned_by_slur': False, 'pitch_content': [(87,), (79,)], 'id': 2} {'fragment': <fragment.GreekFoot Trochee>, 'mod': ('r', 0.125), 'onset_range': (1.25, 1.625), 'is_spanned_by_slur': False, 'pitch_content': [(85,), (80,)], 'id': 3} {'fragment': <fragment.GreekFoot Dactyl>, 'mod': ('r', 0.125), 'onset_range': (1.25, 1.75), 'is_spanned_by_slur': False, 'pitch_content': [(85,), (80,), (80,)], 'id': 40}