Skip to content

Commit

Permalink
Merge pull request #12 from apacha/python2and3
Browse files Browse the repository at this point in the history
Make package Python 2/3 compatible and fix tests
  • Loading branch information
hajicj committed Oct 4, 2018
2 parents abf56bc + b0228fb commit 0442d27
Show file tree
Hide file tree
Showing 20 changed files with 140 additions and 95 deletions.
11 changes: 8 additions & 3 deletions muscima/cropobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
the basic unit of annotation. See the :class:`CropObject` documentation."""
from __future__ import print_function, unicode_literals, division

from builtins import zip
from builtins import map
from builtins import str
from builtins import range
from builtins import object
import copy
import itertools
import logging
Expand Down Expand Up @@ -839,7 +844,7 @@ def encode_data(self, data):
return None

lines = []
for k, v in self.data.items():
for k, v in list(self.data.items()):
vtype = 'str'
vval = v
if isinstance(v, int):
Expand Down Expand Up @@ -868,7 +873,7 @@ def data_display_text(self):
return '[No data]'

lines = []
for k, v in self.data.items():
for k, v in list(self.data.items()):
lines.append('{0}: {1}'.format(k, v))
return '\n'.join(lines)

Expand Down Expand Up @@ -1109,7 +1114,7 @@ def split_cropobject_on_connected_components(c, next_objid):
output = []

_next_objid = next_objid
for label, (t, l, b, r) in bboxes.items():
for label, (t, l, b, r) in list(bboxes.items()):
# Background in compute_connected_components() doesn't work?
if label == 0:
continue
Expand Down
7 changes: 5 additions & 2 deletions muscima/cropobject_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
for annotating MUSCIMA++.
"""
from __future__ import division
from past.utils import old_div
from builtins import object
import logging

__version__ = "1.0"
Expand Down Expand Up @@ -84,7 +87,7 @@ def __str__(self):
'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15,
'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15,
}
_hex_itr = {v: k for k, v in _hex_tr.items()}
_hex_itr = {v: k for k, v in list(_hex_tr.items())}


def parse_hex(hstr):
Expand Down Expand Up @@ -113,7 +116,7 @@ def hex2rgb(hstr):
hstr = hstr[1:]
rs, gs, bs = hstr[:2], hstr[2:4], hstr[4:]
r, g, b = parse_hex(rs), parse_hex(gs), parse_hex(bs)
return r / 255.0, g / 255.0, b / 255.0
return old_div(r, 255.0), old_div(g, 255.0), old_div(b, 255.0)


def rgb2hex(rgb):
Expand Down
5 changes: 4 additions & 1 deletion muscima/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"""
from __future__ import print_function, unicode_literals, division

from builtins import str
from builtins import range
from builtins import object
import logging
import os

Expand Down Expand Up @@ -53,7 +56,7 @@ def _get_mff_muscima_root():
##############################################################################


class CVC_MUSCIMA:
class CVC_MUSCIMA(object):
"""The :class:`CVC_MUSCIMA` class implements a wrapper around
the CVC-MUSCIMA dataset file structure that allows easy retrieval
of filenames based on the page number (1 - 20), writer number
Expand Down
4 changes: 3 additions & 1 deletion muscima/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"""
from __future__ import print_function, unicode_literals

from builtins import str
from builtins import object
import codecs
import logging
import os
Expand Down Expand Up @@ -367,7 +369,7 @@ def find_invalid_in_graph(self, vertices, edges, provide_reasons=False):
reasons_o = {}

# Check that vertices have labels that are in the alphabet
for v, clsname in vertices.items():
for v, clsname in list(vertices.items()):
if clsname not in self.alphabet:
wrong_vertices.append(v)
reasons_v[v] = 'Symbol {0} not in alphabet: class {1}.' \
Expand Down
2 changes: 2 additions & 0 deletions muscima/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
functions for manipulating notation graphs."""
from __future__ import print_function, unicode_literals

from builtins import range
from builtins import object
import copy
import logging

Expand Down
34 changes: 19 additions & 15 deletions muscima/inference.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
"""This module implements a class that..."""
from __future__ import print_function, unicode_literals, division
from builtins import str
from builtins import zip
from builtins import range
from builtins import object
import collections
import copy
import logging
Expand Down Expand Up @@ -174,11 +178,11 @@ def init_base_pitch_default_staffline(self, clef=None):
if transposition_delta != 0:
new_key_accidentals = {
(d + transposition_delta) % 7: v
for d, v in self.key_accidentals.items()
for d, v in list(self.key_accidentals.items())
}
new_inline_accidentals = {
d + transposition_delta: v
for d, v in self.inline_accidentals.items()
for d, v in list(self.inline_accidentals.items())
}
self.key_accidentals = new_key_accidentals
self.inline_accidentals = new_inline_accidentals
Expand Down Expand Up @@ -1153,7 +1157,7 @@ def measure_lasting_beats(self, cropobject):
If any assumption is broken, will return the default measure duration:
4 beats."""
# Find rightmost preceding time signature on the staff.
graph = NotationGraph(self._cdict.values())
graph = NotationGraph(list(self._cdict.values()))

# Find current time signature
staffs = graph.children(cropobject, classes=[_CONST.STAFF_CLSNAME])
Expand Down Expand Up @@ -1329,7 +1333,7 @@ def infer_precedence_from_annotations(self, cropobjects):

if len(systems) == 1:
logging.info('Single-system score, no staff chaining needed.')
source_nodes = [n for n in p_nodes.values() if len(n.inlinks) == 0]
source_nodes = [n for n in list(p_nodes.values()) if len(n.inlinks) == 0]
return source_nodes

# Check all systems same no. of staffs
Expand All @@ -1355,7 +1359,7 @@ def infer_precedence_from_annotations(self, cropobjects):
# - Assign staffs to sink nodes
sink_nodes2staff = {}
staff2sink_nodes = collections.defaultdict(list)
for node in p_nodes.values():
for node in list(p_nodes.values()):
if len(node.outlinks) == 0:
try:
staff = self.__children(node.obj, ['staff'])[0]
Expand All @@ -1379,7 +1383,7 @@ def infer_precedence_from_annotations(self, cropobjects):
# - Assign staffs to source nodes
source_nodes2staff = {}
staff2source_nodes = collections.defaultdict(list)
for node in p_nodes.values():
for node in list(p_nodes.values()):
if len(node.inlinks) == 0:
staff = self.__children(node.obj, ['staff'])[0]
source_nodes2staff[node.obj.objid] = staff.objid
Expand All @@ -1397,7 +1401,7 @@ def infer_precedence_from_annotations(self, cropobjects):
sink.outlinks.append(source)
source.inlinks.append(sink)

source_nodes = [n for n in p_nodes.values() if len(n.inlinks) == 0]
source_nodes = [n for n in list(p_nodes.values()) if len(n.inlinks) == 0]
return source_nodes

def infer_precedence(self, cropobjects):
Expand Down Expand Up @@ -1690,8 +1694,8 @@ def infer_precedence(self, cropobjects):
time_signatures_sorted = sorted(time_signatures,
key=lambda x: time_signatures_to_first_measure[x.objid])
for t1, t2 in zip(time_signatures_sorted[:-1], time_signatures_sorted[1:]):
affected_measures = range(time_signatures_to_first_measure[t1.objid],
time_signatures_to_first_measure[t2.objid])
affected_measures = list(range(time_signatures_to_first_measure[t1.objid],
time_signatures_to_first_measure[t2.objid]))
for i in affected_measures:
# Check for conflicting time signatures previously
# assigned to this measure.
Expand Down Expand Up @@ -1780,8 +1784,8 @@ def infer_precedence(self, cropobjects):
# Iterate over objects left to right, shift measure if next object
# over bound of current measure.
ordered_objs_per_staff = {s_objid: sorted(s_objs, key=lambda x: x.left)
for s_objid, s_objs in staff_to_objs_map.items()}
for s_objid, objs in ordered_objs_per_staff.items():
for s_objid, s_objs in list(staff_to_objs_map.items())}
for s_objid, objs in list(ordered_objs_per_staff.items()):
# Vertically, we don't care -- the attachment to staff takes
# care of that, we only need horizontal placement.
_c_m_idx = 0 # Index of current measure
Expand Down Expand Up @@ -2061,7 +2065,7 @@ def interpret_time_signature(self, time_signature,
numerals_topdown = sorted(numerals, key=lambda c: (c.top + c.bottom) / 2)
gaps = [((c2.bottom + c2.top) / 2) - ((c1.bottom + c2.top) / 2)
for c1, c2 in zip(numerals_topdown[:-1], numerals_topdown[1:])]
largest_gap_idx = max(range(len(gaps)), key=lambda i: gaps[i]) + 1
largest_gap_idx = max(list(range(len(gaps))), key=lambda i: gaps[i]) + 1
numerator = numerals[:largest_gap_idx]
denominator = numerals[largest_gap_idx:]
beat_count = _CONST.interpret_numerals(numerator)
Expand Down Expand Up @@ -2268,7 +2272,7 @@ def _is_note_left(c, _tie, graph):
return new_durations, new_onsets


class PrecedenceGraphNode:
class PrecedenceGraphNode(object):
"""A helper plain-old-data class for onset extraction.
The ``inlinks`` and ``outlinks`` attributes are lists
of other ``PrecedenceGraphNode`` instances.
Expand Down Expand Up @@ -2297,7 +2301,7 @@ def __init__(self, objid=None, cropobject=None, inlinks=None, outlinks=None,
of its descendants in the precedence graph?'''


class MIDIBuilder:
class MIDIBuilder(object):

def midi_matrix_to_pdo(self, midi_matrix, framerate=20, tempo=120):
"""Builds the pitch, duration and onset dicts from a given MIDI
Expand Down Expand Up @@ -2396,7 +2400,7 @@ def build_midi(self, pitches, durations, onsets, selection=None, tempo=120):
channel = 0
volume = 100

keys = pitches.keys()
keys = list(pitches.keys())

min_onset = 0
if selection is not None:
Expand Down
2 changes: 2 additions & 0 deletions muscima/inference_engine_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
duration and onset inference algorithm."""
from __future__ import print_function, unicode_literals, division

from builtins import range
from builtins import object
import operator

__version__ = "0.0.1"
Expand Down
4 changes: 3 additions & 1 deletion muscima/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@
"""
from __future__ import print_function, unicode_literals, division

from builtins import str
from builtins import map
import copy
import logging
import os
Expand Down Expand Up @@ -499,7 +501,7 @@ def validate_cropobjects_graph_structure(cropobjects):
cropobjects_by_doc[c.doc].append(c)

is_valid = True
for doc, doc_cropobjects in cropobjects_by_doc.items():
for doc, doc_cropobjects in list(cropobjects_by_doc.items()):
doc_is_valid = validate_document_graph_structure(doc_cropobjects)
if not doc_is_valid:
logging.warning('Document {0} has invalid cropobject graph!'
Expand Down
12 changes: 7 additions & 5 deletions muscima/stafflines.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
e.g. by pressing "shift+s" in MUSCIMarker."""
from __future__ import print_function, unicode_literals, division

from builtins import zip
from builtins import range
import collections
import logging
import pprint
Expand Down Expand Up @@ -151,7 +153,7 @@ def staffline_bboxes_and_masks_from_horizontal_merge(mask):
n_rows, n_cols = mask.shape
# For each row of the image: which CCs have pxs on that row?
intervals = [[] for _ in range(n_rows)]
for label, (t, l, b, r) in bboxes.items():
for label, (t, l, b, r) in list(bboxes.items()):
if label == 0:
continue
# Ignore very short staffline segments that can easily be artifacts
Expand Down Expand Up @@ -607,7 +609,7 @@ def add_staff_relationships(cropobjects,
# Symbol -> staff?
# It does not really matter, but it's more intuitive to attach symbols
# onto a pre-existing staff. So, symbol -> staff.
for clsname, cs in staff_related_symbols.items():
for clsname, cs in list(staff_related_symbols.items()):
for c in cs:
# Find the related staff. Relatedness is measured by row overlap.
# That means we have to modify the staff bounding box to lead
Expand All @@ -622,7 +624,7 @@ def add_staff_relationships(cropobjects,

##########################################################################
logging.info('Adding rest --> staff relationships.')
for clsname, cs in rest_symbols.items():
for clsname, cs in list(rest_symbols.items()):
for c in cs:
closest_staff = min([s for s in staffs],
key=lambda x: ((x.bottom + x.top) / 2. - (c.bottom + c.top) / 2.) ** 2)
Expand Down Expand Up @@ -703,7 +705,7 @@ def add_staff_relationships(cropobjects,
# dt, dl, db, dr = s.top - t, s.left - l, s.bottom - t, s.right - l
# staffline_canvas[dt:db, dl:dr] += s.mask

for clsname, cs in notehead_symbols.items():
for clsname, cs in list(notehead_symbols.items()):
for c in cs:

ct, cl, cb, cr = c.bounding_box
Expand Down Expand Up @@ -829,7 +831,7 @@ def add_staff_relationships(cropobjects,
''.format(c.uid))
continue

_ss_i_max = max(overlapped_staffspaces.keys(),
_ss_i_max = max(list(overlapped_staffspaces.keys()),
key=lambda x: overlapped_staffspaces[x])
max_overlap_staffspace = staffspaces[_ss_i_max]
link_cropobjects(c, max_overlap_staffspace, check_docname=False)
Expand Down
4 changes: 3 additions & 1 deletion muscima/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""This module implements a class that..."""
from __future__ import print_function, unicode_literals
from __future__ import division

from past.utils import old_div
import logging

from skimage.measure import label
Expand Down Expand Up @@ -95,7 +97,7 @@ def resolve_notehead_wrt_staffline(notehead, staffline_or_ledger_line):
dtop = ll.top - notehead.top
dbottom = notehead.bottom - ll.bottom

if min(dtop, dbottom) / max(dtop, dbottom) \
if old_div(min(dtop, dbottom), max(dtop, dbottom)) \
< _CONST.ON_STAFFLINE_RATIO_TRHESHOLD:
if dtop > dbottom:
output_position = 1
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ scikit-learn
matplotlib
midiutil>=1.2.1
midi2audio>=0.1.1
future

# Libraries to integrating code-coverage reporting
python-coveralls
Expand Down
8 changes: 4 additions & 4 deletions scripts/add_staff_relationships.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def add_staff_relationships(cropobjects,
# Symbol -> staff?
# It does not really matter, but it's more intuitive to attach symbols
# onto a pre-existing staff. So, symbol -> staff.
for clsname, cs in staff_related_symbols.items():
for clsname, cs in list(staff_related_symbols.items()):
for c in cs:
# Find the related staff. Relatedness is measured by row overlap.
# That means we have to modify the staff bounding box to lead
Expand All @@ -111,7 +111,7 @@ def add_staff_relationships(cropobjects,

##########################################################################
logging.info('Adding rest --> staff relationships.')
for clsname, cs in rest_symbols.items():
for clsname, cs in list(rest_symbols.items()):
for c in cs:
closest_staff = min([s for s in staffs],
key=lambda x: ((x.bottom + x.top) / 2. - (c.bottom + c.top) / 2.) ** 2)
Expand Down Expand Up @@ -188,7 +188,7 @@ def add_staff_relationships(cropobjects,
# dt, dl, db, dr = s.top - t, s.left - l, s.bottom - t, s.right - l
# staffline_canvas[dt:db, dl:dr] += s.mask

for clsname, cs in notehead_symbols.items():
for clsname, cs in list(notehead_symbols.items()):
for c in cs:

ct, cl, cb, cr = c.bounding_box
Expand Down Expand Up @@ -302,7 +302,7 @@ def add_staff_relationships(cropobjects,
if len(overlapped_staffspaces) == 0:
logging.warn('Notehead {0}: no overlapped staffline object, no ledger line!'
''.format(c.uid))
_ss_i_max = max(overlapped_staffspaces.keys(),
_ss_i_max = max(list(overlapped_staffspaces.keys()),
key=lambda x: overlapped_staffspaces[x])
max_overlap_staffspace = staffspaces[_ss_i_max]
link_cropobjects(c, max_overlap_staffspace)
Expand Down
Loading

0 comments on commit 0442d27

Please sign in to comment.