How to use sub method in autotest

Best Python code snippet using autotest_python

convertrules.py

Source:convertrules.py Github

copy

Full Screen

...1549 str )1550 return str1551@rule ((2, 3, 24), _ ('''regularize other identifiers'''))1552def conv (str):1553 def sub(m):1554 return regularize_id (m.group (1))1555 str = re.sub (r'(maintainer_email|maintainer_web|midi_stuff|gourlay_maxmeasures)',1556 sub, str)1557 return str1558@rule ((2, 3, 25), 'petrucci_c1 -> petrucci-c1, 1style -> single-digit')1559def conv (str):1560 str = re.sub ('petrucci_c1', 'petrucci-c1', str)1561 str = re.sub ('1style', 'single-digit', str)1562 return str1563@rule ((2, 4, 0), _ ("bump version for release"))1564def conv (str):1565 return str1566@rule ((2, 5, 0), '\\quote -> \\quoteDuring')1567def conv (str):1568 str = re.sub (r'\\quote\s+"?([a-zA-Z0-9]+)"?\s+([0-9.*/]+)',1569 r'\\quoteDuring #"\1" { \skip \2 }',1570 str)1571 return str1572@rule ((2, 5, 1), 'ly:import-module -> ly:module-copy')1573def conv (str):1574 str = re.sub (r'ly:import-module',1575 r'ly:module-copy', str)1576 return str1577@rule ((2, 5, 2), '\markup .. < .. > .. -> \markup .. { .. } ..')1578def conv (str):1579 str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',1580 r'\\\1 {\2}', str)1581 str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',1582 r'\\\1 {\2}', str)1583 str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',1584 r'\\\1 {\2}', str)1585 def get_markup (m):1586 s = m.group (0)1587 s = re.sub (r'''((\\"|})\s*){''', '\2 \\line {', s)1588 return s1589 str = re.sub (r'\\markup\s*{([^}]|{[^}]*})*}', get_markup, str)1590 return str1591@rule ((2, 5, 3), 'ly:find-glyph-by-name -> ly:font-get-glyph, remove - from glyphnames.')1592def conv (str):1593 str = re.sub ('ly:find-glyph-by-name', 'ly:font-get-glyph', str)1594 str = re.sub ('"(scripts|clefs|accidentals)-', r'"\1.', str)1595 str = re.sub ("'hufnagel-do-fa", "'hufnagel.do.fa", str)1596 str = re.sub ("'(vaticana|hufnagel|medicaea|petrucci|neomensural|mensural)-", r"'\1.", str)1597 return str1598@rule ((2, 5, 12), '\set Slur #\'dashed = #X -> \slurDashed')1599def conv (str):1600 str = re.sub (r"\\override\s+(Voice\.)?Slur #'dashed\s*=\s*#\d*(\.\d+)?",1601 r"\\slurDashed", str)1602 return str1603@rule ((2, 5, 13), _ ('\\encoding: smart recode latin1..utf-8. Remove ly:point-and-click'))1604def conv (str):1605 input_encoding = 'latin1'1606 def func (match):1607 encoding = match.group (1)1608 # FIXME: automatic recoding of other than latin1?1609 if encoding == 'latin1':1610 return match.group (2)1611 stderr_write (NOT_SMART % ("\\encoding: %s" % encoding))1612 stderr_write (_ ("LilyPond source must be UTF-8"))1613 stderr_write ('\n')1614 if encoding == 'TeX':1615 stderr_write (_ ("Try the texstrings backend"))1616 stderr_write ('\n')1617 else:1618 stderr_write ( _("Do something like: %s") % \1619 ("recode %s..utf-8 FILE" % encoding))1620 stderr_write ('\n')1621 stderr_write (_ ("Or save as UTF-8 in your editor"))1622 stderr_write ('\n')1623 raise FatalConversionError ()1624 return match.group (0)1625 str = re.sub (r'\\encoding\s+"?([a-zA-Z0-9]+)"?(\s+)', func, str)1626 import codecs1627 de_ascii = codecs.getdecoder ('ascii')1628 de_utf_8 = codecs.getdecoder ('utf_8')1629 de_input = codecs.getdecoder (input_encoding)1630 en_utf_8 = codecs.getencoder ('utf_8')1631 try:1632 de_ascii (str)1633 # only in python >= 2.31634 # except UnicodeDecodeError:1635 except UnicodeError:1636 # do not re-recode UTF-8 input1637 try:1638 de_utf_8 (str)1639 #except UnicodeDecodeError:1640 except UnicodeError:1641 str = en_utf_8 (de_input (str)[0])[0]1642 str = re.sub (r"#\(ly:set-point-and-click '[a-z-]+\)", '', str)1643 return str1644@rule ((2, 5, 17), _ ('remove %s') % 'ly:stencil-set-extent!')1645def conv (str):1646 if re.search ("ly:stencil-set-extent!", str):1647 stderr_write (NOT_SMART % "ly:stencil-set-extent!")1648 stderr_write (_ ('Use %s\n') % '(set! VAR (ly:make-stencil (ly:stencil-expr VAR) X-EXT Y-EXT))')1649 raise FatalConversionError ()1650 if re.search ("ly:stencil-align-to!", str):1651 stderr_write (NOT_SMART % "ly:stencil-align-to!")1652 stderr_write (_ ('Use %s\n') % '(set! VAR (ly:stencil-aligned-to VAR AXIS DIR))')1653 raise FatalConversionError ()1654 return str1655@rule ((2, 5, 18), 'ly:warn -> ly:warning')1656def conv (str):1657 str = re.sub (r"ly:warn\b", 'ly:warning', str)1658 return str1659@rule ((2, 5, 21), _ ('warn about auto beam settings'))1660def conv (str):1661 if re.search ("(override-|revert-)auto-beam-setting", str)\1662 or re.search ("autoBeamSettings", str):1663 stderr_write (NOT_SMART % _ ("auto beam settings"))1664 stderr_write (_ ('''1665Auto beam settings must now specify each interesting moment in a measure1666explicitly; 1/4 is no longer multiplied to cover moments 1/2 and 3/4 too.1667'''))1668 stderr_write (UPDATE_MANUALLY)1669 raise FatalConversionError ()1670 return str1671@rule ((2, 5, 25), 'unfoldrepeats -> unfoldRepeats, compressmusic -> compressMusic')1672def conv (str):1673 str = re.sub (r"unfoldrepeats", 'unfoldRepeats', str)1674 str = re.sub (r"compressmusic", 'compressMusic', str)1675 return str1676@rule ((2, 6, 0), _ ("bump version for release"))1677def conv (str):1678 return str1679@rule ((2, 7, 0), 'ly:get-default-font -> ly:grob-default-font')1680def conv (str):1681 return re.sub('ly:get-default-font', 'ly:grob-default-font', str)1682@rule ((2, 7, 1), '''ly:parser-define -> ly:parser-define!1683excentricity -> eccentricity1684Timing_engraver -> Timing_translator + Default_bar_line_engraver1685''')1686def conv (str):1687 str = re.sub('ly:parser-define', 'ly:parser-define!', str)1688 str = re.sub('excentricity', 'eccentricity', str)1689 str = re.sub(r'\\(consists|remove) *"?Timing_engraver"?',1690 r'\\\1 "Timing_translator" \\\1 "Default_bar_line_engraver"',1691 str)1692 return str1693@rule ((2, 7, 2), 'ly:X-moment -> ly:moment-X')1694def conv (str):1695 str = re.sub('ly:(add|mul|mod|div)-moment', r'ly:moment-\1', str)1696 return str1697@rule ((2, 7, 4), 'keyAccidentalOrder -> keyAlterationOrder')1698def conv (str):1699 str = re.sub('keyAccidentalOrder', 'keyAlterationOrder', str)1700 return str1701@rule ((2, 7, 6), '''Performer_group_performer -> Performer_group, Engraver_group_engraver -> Engraver_group,1702inside-slur -> avoid-slur''')1703def conv (str):1704 str = re.sub('Performer_group_performer', 'Performer_group', str)1705 str = re.sub('Engraver_group_engraver', 'Engraver_group', str)1706 str = re.sub (r"#'inside-slur\s*=\s*##t *",1707 r"#'avoid-slur = #'inside ", str)1708 str = re.sub (r"#'inside-slur\s*=\s*##f *",1709 r"#'avoid-slur = #'around ", str)1710 str = re.sub (r"#'inside-slur",1711 r"#'avoid-slur", str)1712 return str1713@rule ((2, 7, 10), '\\applyxxx -> \\applyXxx')1714def conv (str):1715 str = re.sub(r'\\applyoutput', r'\\applyOutput', str)1716 str = re.sub(r'\\applycontext', r'\\applyContext', str)1717 str = re.sub(r'\\applymusic', r'\\applyMusic', str)1718 str = re.sub(r'ly:grob-suicide', 'ly:grob-suicide!', str)1719 return str1720@rule ((2, 7, 11), '"tabloid" -> "11x17"')1721def conv (str):1722 str = re.sub(r'\"tabloid\"', '"11x17"', str)1723 return str1724@rule ((2, 7, 12), 'outputProperty -> overrideProperty')1725def conv (str):1726 str = re.sub(r'outputProperty' , 'overrideProperty', str)1727 return str1728@rule ((2, 7, 13), 'layout engine refactoring [FIXME]')1729def conv (str):1730 def subber (match):1731 newkey = {'spacing-procedure': 'springs-and-rods',1732 'after-line-breaking-callback' : 'after-line-breaking',1733 'before-line-breaking-callback' : 'before-line-breaking',1734 'print-function' : 'stencil'} [match.group(3)]1735 what = match.group (1)1736 grob = match.group (2)1737 if what == 'revert':1738 return "revert %s #'callbacks %% %s\n" % (grob, newkey)1739 elif what == 'override':1740 return "override %s #'callbacks #'%s" % (grob, newkey)1741 else:1742 raise 'urg'1743 return ''1744 str = re.sub(r"(override|revert)\s*([a-zA-Z.]+)\s*#'(spacing-procedure|after-line-breaking-callback"1745 + r"|before-line-breaking-callback|print-function)",1746 subber, str)1747 if re.search ('bar-size-procedure', str):1748 stderr_write (NOT_SMART % "bar-size-procedure")1749 if re.search ('space-function', str):1750 stderr_write (NOT_SMART % "space-function")1751 if re.search ('verticalAlignmentChildCallback', str):1752 stderr_write (_ ('verticalAlignmentChildCallback has been deprecated'))1753 stderr_write ('\n')1754 return str1755@rule ((2, 7, 14), _ ('Remove callbacks property, deprecate XY-extent-callback.'))1756def conv (str):1757 str = re.sub (r"\\override +([A-Z.a-z]+) #'callbacks",1758 r"\\override \1", str)1759 str = re.sub (r"\\revert ([A-Z.a-z]+) #'callbacks % ([a-zA-Z]+)",1760 r"\\revert \1 #'\2", str)1761 str = re.sub (r"([XY]-extent)-callback", r'\1', str)1762 str = re.sub (r"RemoveEmptyVerticalGroup", "VerticalAxisGroup", str)1763 str = re.sub (r"\\set ([a-zA-Z]*\.?)minimumVerticalExtent",1764 r"\\override \1VerticalAxisGroup #'minimum-Y-extent",1765 str)1766 str = re.sub (r"minimumVerticalExtent",1767 r"\\override VerticalAxisGroup #'minimum-Y-extent",1768 str)1769 str = re.sub (r"\\set ([a-zA-Z]*\.?)extraVerticalExtent",1770 r"\\override \1VerticalAxisGroup #'extra-Y-extent", str)1771 str = re.sub (r"\\set ([a-zA-Z]*\.?)verticalExtent",1772 r"\\override \1VerticalAxisGroup #'Y-extent", str)1773 return str1774@rule ((2, 7, 15), _ ('Use grob closures iso. XY-offset-callbacks.'))1775def conv (str):1776 if re.search ('[XY]-offset-callbacks', str):1777 stderr_write (NOT_SMART % "[XY]-offset-callbacks")1778 if re.search ('position-callbacks', str):1779 stderr_write (NOT_SMART % "position-callbacks")1780 return str1781@rule ((2, 7, 22), r"\tag #'(a b) -> \tag #'a \tag #'b")1782def conv (str):1783 def sub_syms (m):1784 syms = m.group (1).split ()1785 tags = ["\\tag #'%s" % s for s in syms]1786 return ' '.join (tags)1787 str = re.sub (r"\\tag #'\(([^)]+)\)", sub_syms, str)1788 return str1789@rule ((2, 7, 24), _ ('deprecate %s') % 'number-visibility')1790def conv (str):1791 str = re.sub (r"#'number-visibility",1792 "#'number-visibility % number-visibility is deprecated. Tune the TupletNumber instead\n",1793 str)1794 return str1795@rule ((2, 7, 28), "ly:spanner-get-bound -> ly:spanner-bound")1796def conv (str):1797 str = re.sub (r"ly:spanner-get-bound", "ly:spanner-bound", str)1798 return str1799@rule ((2, 7, 29), "override Stem #'beamed-* -> #'details #'beamed-*")1800def conv (str):1801 for a in ['beamed-lengths', 'beamed-minimum-free-lengths',1802 'lengths',1803 'beamed-extreme-minimum-free-lengths']:1804 str = re.sub (r"\\override\s+Stem\s+#'%s" % a,1805 r"\\override Stem #'details #'%s" % a,1806 str)1807 return str1808@rule ((2, 7, 30), "\\epsfile")1809def conv (str):1810 str = re.sub (r'\\epsfile *#"', r'\\epsfile #X #10 #"', str)1811 return str1812@rule ((2, 7, 31), "Foo_bar::bla_bla -> ly:foo-bar::bla-bla")1813def conv (str):1814 def sub_cxx_id (m):1815 str = m.group(1)1816 return 'ly:' + str.lower ().replace ('_','-')1817 str = re.sub (r'([A-Z][a-z_0-9]+::[a-z_0-9]+)',1818 sub_cxx_id, str)1819 return str1820@rule ((2, 7, 32), _ ("foobar -> foo-bar for \paper, \layout"))1821def conv (str):1822 identifier_subs = [1823 ('inputencoding', 'input-encoding'),1824 ('printpagenumber', 'print-page-number'),1825 ('outputscale', 'output-scale'),1826 ('betweensystemspace', 'between-system-space'),1827 ('betweensystempadding', 'between-system-padding'),1828 ('pagetopspace', 'page-top-space'),1829 ('raggedlastbottom', 'ragged-last-bottom'),1830 ('raggedright', 'ragged-right'),1831 ('raggedlast', 'ragged-last'),1832 ('raggedbottom', 'ragged-bottom'),1833 ('aftertitlespace', 'after-title-space'),1834 ('beforetitlespace', 'before-title-space'),1835 ('betweentitlespace', 'between-title-space'),1836 ('topmargin', 'top-margin'),1837 ('bottommargin', 'bottom-margin'),1838 ('headsep', 'head-separation'),1839 ('footsep', 'foot-separation'),1840 ('rightmargin', 'right-margin'),1841 ('leftmargin', 'left-margin'),1842 ('printfirstpagenumber', 'print-first-page-number'),1843 ('firstpagenumber', 'first-page-number'),1844 ('hsize', 'paper-width'),1845 ('vsize', 'paper-height'),1846 ('horizontalshift', 'horizontal-shift'),1847 ('staffspace', 'staff-space'),1848 ('linethickness', 'line-thickness'),1849 ('ledgerlinethickness', 'ledger-line-thickness'),1850 ('blotdiameter', 'blot-diameter'),1851 ('staffheight', 'staff-height'),1852 ('linewidth', 'line-width'),1853 ('annotatespacing', 'annotate-spacing')1854 ]1855 for (a,b) in identifier_subs:1856 ### for C++:1857 ## str = re.sub ('"%s"' % a, '"%s"' b, str)1858 str = re.sub (a, b, str)1859 return str1860@rule ((2, 7, 32), "debug-beam-quanting -> debug-beam-scoring")1861def conv (str):1862 str = re.sub ('debug-beam-quanting', 'debug-beam-scoring', str)1863 return str1864@rule ((2, 7, 36), "def-(music-function|markup-command) -> define-(music-function|markup-command)")1865def conv (str):1866 str = re.sub ('def-music-function', 'define-music-function', str)1867 str = re.sub ('def-markup-command', 'define-markup-command', str)1868 return str1869@rule ((2, 7, 40), "rehearsalMarkAlignSymbol/barNumberAlignSymbol -> break-align-symbol")1870def conv (str):1871 str = re.sub (r'\\set\s+Score\s*\.\s*barNumberAlignSymbol\s*=',1872 r"\\override Score.BarNumber #'break-align-symbol = ", str)1873 str = re.sub (r'\\set\s*Score\s*\.\s*rehearsalMarkAlignSymbol\s*=',1874 r"\\override Score.RehearsalMark #'break-align-symbol = ", str)1875 return str1876@rule ((2, 9, 4), "(page-)penalty -> (page-)break-penalty")1877def conv (str):1878 str = re.sub ('page-penalty', 'page-break-penalty', str)1879 str = re.sub ('([^-])penalty', '\1break-penalty', str)1880 return str1881@rule ((2, 9, 6), "\\context Foo \\applyOutput #bla -> \\applyOutput #'Foo #bla ")1882def conv (str):1883 str = re.sub (r'\\context\s+\"?([a-zA-Z]+)\"?\s*\\applyOutput', r"\\applyOutput #'\1", str)1884 return str1885@rule ((2, 9, 9), "annotatefoo -> annotate-foo")1886def conv (str):1887 str = re.sub ('annotatepage', 'annotate-page', str)1888 str = re.sub ('annotateheaders', 'annotate-headers', str)1889 str = re.sub ('annotatesystems', 'annotate-systems', str)1890 return str1891@rule ((2, 9, 11), "\\set tupletNumberFormatFunction -> \\override #'text = ")1892def conv (str):1893 str = re.sub (r"""(\\set\s)?(?P<context>[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#denominator-tuplet-formatter""",1894 r"""\\override \g<context>TupletNumber #'text = #tuplet-number::calc-denominator-text""", str)1895 str = re.sub (r"""(\\set\s+)?(?P<context>[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#fraction-tuplet-formatter""",1896 r"""\\override \g<context>TupletNumber #'text = #tuplet-number::calc-fraction-text""", str)1897 if re.search ('tupletNumberFormatFunction', str):1898 stderr_write ("\n")1899 stderr_write ("tupletNumberFormatFunction has been removed. Use #'text property on TupletNumber")1900 stderr_write ("\n")1901 return str1902@rule ((2, 9, 13), "instrument -> instrumentName, instr -> shortInstrumentName, vocNam -> shortVocalName")1903def conv (str):1904 str = re.sub ('vocNam', 'shortVocalName', str)1905 str = re.sub (r'\.instr\s*=', r'.shortInstrumentName =', str)1906 str = re.sub (r'\.instrument\s*=', r'.instrumentName =', str)1907 return str1908@rule ((2, 9, 16), _ ("deprecate \\tempo in \\midi"))1909def conv (str):1910 def sub_tempo (m):1911 dur = int (m.group (1))1912 dots = len (m.group (2))1913 count = int (m.group (3))1914 log2 = 01915 while dur > 1 :1916 dur /= 21917 log2 += 11918 den = (1 << dots) * (1 << log2)1919 num = ((1 << (dots+1)) - 1)1920 return """1921 \midi {1922 \context {1923 \Score1924 tempoWholesPerMinute = #(ly:make-moment %d %d)1925 }1926 }1927""" % (num*count, den)1928 str = re.sub (r'\\midi\s*{\s*\\tempo ([0-9]+)\s*([.]*)\s*=\s*([0-9]+)\s*}', sub_tempo, str)1929 return str1930@rule ((2, 9, 19), "printfirst-page-number -> print-first-page-number")1931def conv (str):1932 str = re.sub ('printfirst-page-number', 'print-first-page-number', str)1933 return str1934@rule ((2, 10, 0), _ ("bump version for release"))1935def conv (str):1936 return str1937@rule ((2, 11, 2), "ly:clone-parser -> ly:parser-clone")1938def conv (str):1939 return re.sub ('ly:clone-parser',1940 'ly:parser-clone', str)1941@rule ((2, 11, 3), "no-spacing-rods -> extra-spacing-width")1942def conv (str):1943 str = re.sub (r"no-spacing-rods\s+=\s+##t", r"extra-spacing-width = #'(+inf.0 . -inf.0)", str)1944 str = re.sub (r"no-spacing-rods\s+=\s+##f", r"extra-spacing-width = #'(0 . 0)", str)1945 return str1946@rule ((2, 11, 5), _ ("deprecate cautionary-style. Use AccidentalCautionary properties"))1947def conv (str):1948 str = re.sub ("Accidental\s*#'cautionary-style\s*=\s*#'smaller",1949 "AccidentalCautionary #'font-size = #-2", str)1950 str = re.sub ("Accidental\s*#'cautionary-style\s*=\s*#'parentheses",1951 "AccidentalCautionary #'parenthesized = ##t", str)1952 str = re.sub ("([A-Za-z]+)\s*#'cautionary-style\s*=\s*#'parentheses",1953 r"\1 #'parenthesized = ##t", str)1954 str = re.sub ("([A-Za-z]+)\s*#'cautionary-style\s*=\s*#'smaller",1955 r"\1 #'font-size = #-2", str)1956 return str1957@rule ((2, 11, 6), _ ("Rename accidental glyphs, use glyph-name-alist."))1958def conv (str):1959 def sub_acc_name (m):1960 idx = int (m.group (1).replace ('M','-'))1961 return ["accidentals.doublesharp",1962 "accidentals.sharp.slashslash.stemstemstem",1963 "accidentals.sharp",1964 "accidentals.sharp.slashslash.stem",1965 "accidentals.natural",1966 "accidentals.mirroredflat",1967 "accidentals.flat",1968 "accidentals.mirroredflat.flat",1969 "accidentals.flatflat"][4-idx]1970 str = re.sub (r"accidentals[.](M?[-0-9]+)",1971 sub_acc_name, str)1972 str = re.sub (r"(KeySignature|Accidental[A-Za-z]*)\s*#'style\s*=\s*#'([a-z]+)",1973 r"\1 #'glyph-name-alist = #alteration-\2-glyph-name-alist", str)1974 ## FIXME: standard vs default, alteration-FOO vs FOO-alteration1975 str = str.replace ('alteration-default-glyph-name-alist',1976 'standard-alteration-glyph-name-alist')1977 return str1978@rule ((2, 11, 10), """allowBeamBreak -> Beam #'breakable = ##t1979addquote -> addQuote1980""")1981def conv (str):1982 str = re.sub (r'(\\set\s+)?([A-Z][a-zA-Z]+\s*\.\s*)allowBeamBreak',1983 r"\override \2Beam #'breakable", str)1984 str = re.sub (r'(\\set\s+)?allowBeamBreak',1985 r"\override Beam #'breakable", str)1986 str = re.sub (r'addquote', 'addQuote', str)1987 if re.search ("Span_dynamic_performer", str):1988 stderr_write ("Span_dynamic_performer has been merged into Dynamic_performer")1989 return str1990@rule ((2, 11, 11), "layout-set-staff-size -> layout-set-absolute-staff-size")1991def conv (str):1992 str = re.sub (r'\(layout-set-staff-size \(\*\s*([0-9.]+)\s*(pt|mm|cm)\)\)',1993 r'(layout-set-absolute-staff-size (* \1 \2))', str)1994 return str1995@rule ((2, 11, 13), "#'arrow = ##t -> #'bound-details #'right #'arrow = ##t")1996def conv (str):1997 str = re.sub (r"\\override\s*([a-zA-Z.]+)\s*#'arrow\s*=\s*##t",1998 r"\\override \1 #'bound-details #'right #'arrow = ##t",1999 str)2000 if re.search ('edge-text', str):2001 stderr_write (NOT_SMART % _ ("edge-text settings for TextSpanner"))2002 stderr_write (_ ("Use\n\n%s") %2003 "\t\\override TextSpanner #'bound-details #'right #'text = <right-text>\n"2004 "\t\\override TextSpanner #'bound-details #'left #'text = <left-text>\n")2005 return str2006@rule ((2, 11, 15), "TextSpanner #'edge-height -> #'bound-details #'right/left #'text = ...\n\2007Remove 'forced-distance for fixed spacing between staves in a PianoStaff.")2008def conv (str):2009 def sub_edge_height (m):2010 s = ''2011 for (var, h) in [('left', m.group (3)),2012 ('right', m.group (4))]:2013 if h and float (h):2014 once = m.group (1)2015 if not once:2016 once = ''2017 context = m.group (2)2018 if not context:2019 context = ''2020 s += (r"%s \override %sTextSpanner #'bound-details #'%s #'text = \markup { \draw-line #'(0 . %s) }"2021 % (once, context, var, h))2022 s += '\n'2023 return s2024 str = re.sub (r"(\\once)?\s*\\override\s*([a-zA-Z]+\s*[.]\s*)?TextSpanner\s*#'edge-height\s*=\s*#'\(\s*([0-9.-]+)\s+[.]\s+([0-9.-]+)\s*\)", sub_edge_height, str)2025 if re.search (r"#'forced-distance", str):2026 stderr_write (NOT_SMART % "VerticalAlignment #'forced-distance")2027 stderr_write (_ ("Use the `alignment-offsets' sub-property of\n"))2028 stderr_write (_ ("NonMusicalPaperColumn #'line-break-system-details\n"))2029 stderr_write (_ ("to set fixed distances between staves.\n"))2030 return str2031@rule ((2, 11, 23), "#'break-align-symbol -> #'break-align-symbols")2032def conv (str):2033 str = re.sub (r"\\override\s*([a-zA-Z.]+)\s*#'break-align-symbol\s*=\s*#'([a-z-]+)",2034 r"\\override \1 #'break-align-symbols = #'(\2)", str)2035 return str2036@rule ((2, 11, 35), """scripts.caesura -> scripts.caesura.curved.2037""" + _ ("Use #'style not #'dash-fraction to select solid/dashed lines."))2038def conv (str):2039 str = re.sub (r"scripts\.caesura",2040 r"scripts.caesura.curved", str)2041 if re.search ('dash-fraction', str):2042 stderr_write (NOT_SMART % _ ("all settings related to dashed lines"))2043 stderr_write (_ ("Use \\override ... #'style = #'line for solid lines and\n"))2044 stderr_write (_ ("\t\\override ... #'style = #'dashed-line for dashed lines."))2045 return str2046@rule ((2, 11, 38), """\\setEasyHeads -> \\easyHeadsOn, \\fatText -> \\textLengthOn,2047\\emptyText -> \\textLengthOff""")2048def conv (str):2049 str = re.sub (r"setEasyHeads", r"easyHeadsOn", str)2050 str = re.sub (r"fatText", r"textLengthOn", str)2051 str = re.sub (r"emptyText", r"textLengthOff", str)2052 return str2053@rule ((2, 11, 46), "\\set hairpinToBarline -> \\override Hairpin #'to-barline")2054def conv (str):2055 str = re.sub (r"\\set\s+([a-zA-Z]+)\s*.\s*hairpinToBarline\s*=\s*##([tf]+)",2056 r"\\override \1.Hairpin #'to-barline = ##\2", str)2057 str = re.sub (r"\\set\s+hairpinToBarline\s*=\s*##([tf]+)",2058 r"\\override Hairpin #'to-barline = ##\1", str)2059 str = re.sub (r"\\unset\s+([a-zA-Z]+)\s*.\s*hairpinToBarline",2060 r"\\revert \1.Hairpin #'to-barline", str)2061 str = re.sub (r"\\unset\s+hairpinToBarline",2062 r"\\revert Hairpin #'to-barline", str)2063 str = re.sub (r"hairpinToBarline\s*=\s*##([tf]+)",2064 r"\\override Hairpin #'to-barline = ##\1", str)2065 str = re.sub (r"\\set (de|)crescendoSpanner = #'dashed-line",2066 r"\\set \1crescendoSpanner = #'text", str)2067 return str2068@rule ((2, 11, 48), "\\compressMusic -> \\scaleDurations")2069def conv (str):2070 str = re.sub (r"compressMusic", r"scaleDurations", str)2071 return str2072@rule ((2, 11, 50), _ ("metronomeMarkFormatter uses text markup as second argument,\n\2073fret diagram properties moved to fret-diagram-details."))2074def conv (str):2075 ## warning 1/2: metronomeMarkFormatter uses text markup as second argument2076 if re.search ('metronomeMarkFormatter', str):2077 stderr_write (NOT_SMART % "metronomeMarkFormatter")2078 stderr_write (_ ("metronomeMarkFormatter got an additional text argument.\n"))2079 stderr_write (_ ("The function assigned to Score.metronomeMarkFunction now uses the signature\n%s") %2080 "\t(format-metronome-markup text dur count context)\n")2081 ## warning 2/2: fret diagram properties moved to fret-diagram-details2082 fret_props = ['barre-type',2083 'dot-color',2084 'dot-radius',2085 'finger-code',2086 'fret-count',2087 'label-dir',2088 'number-type',2089 'string-count',2090 'xo-font-magnification',2091 'mute-string',2092 'open-string',2093 'orientation']2094 for prop in fret_props:2095 if re.search (prop, str):2096 stderr_write (NOT_SMART % (_ ("%s in fret-diagram properties") % prop))2097 stderr_write (_ ('Use %s\n') % "fret-diagram-details")2098 return str2099@rule ((2, 11, 51), "\\octave -> \\octaveCheck, \\arpeggioUp -> \\arpeggioArrowUp,\n\2100\\arpeggioDown -> \\arpeggioArrowDown, \\arpeggioNeutral -> \\arpeggioNormal,\n\2101\\setTextCresc -> \\crescTextCresc, \\setTextDecresc -> \\dimTextDecresc,\n\2102\\setTextDecr -> \\dimTextDecr, \\setTextDim -> \\dimTextDim,\n\2103\\setHairpinCresc -> \\crescHairpin, \\setHairpinDecresc -> \\dimHairpin,\n\2104\\sustainUp -> \\sustainOff, \\sustainDown -> \\sustainOn\n\2105\\sostenutoDown -> \\sostenutoOn, \\sostenutoUp -> \\sostenutoOff")2106def conv (str):2107 str = re.sub (r"\\octave(?![a-zA-Z])", r"\\octaveCheck", str)2108 str = re.sub (r"arpeggioUp", r"arpeggioArrowUp", str)2109 str = re.sub (r"arpeggioDown", r"arpeggioArrowDown", str)2110 str = re.sub (r"arpeggioNeutral", r"arpeggioNormal", str)2111 str = re.sub (r"setTextCresc", r"crescTextCresc", str)2112 str = re.sub (r"setTextDecresc", r"dimTextDecresc", str)2113 str = re.sub (r"setTextDecr", r"dimTextDecr", str)2114 str = re.sub (r"setTextDim", r"dimTextDim", str)2115 str = re.sub (r"setHairpinCresc", r"crescHairpin", str)2116 str = re.sub (r"setHairpinDecresc", r"dimHairpin", str)2117 str = re.sub (r"sustainUp", r"sustainOff", str)2118 str = re.sub (r"sustainDown", r"sustainOn", str)2119 str = re.sub (r"sostenutoDown", r"sostenutoOn", str)2120 str = re.sub (r"sostenutoUp", r"sostenutoOff", str)2121 return str2122@rule ((2, 11, 52), "\\setHairpinDim -> \\dimHairpin")2123def conv (str):2124 str = str.replace ("setHairpinDim", "dimHairpin")2125 return str2126@rule ((2, 11, 53), "infinite-spacing-height -> extra-spacing-height")2127def conv (str):2128 str = re.sub (r"infinite-spacing-height\s+=\s+##t", r"extra-spacing-height = #'(-inf.0 . +inf.0)", str)2129 str = re.sub (r"infinite-spacing-height\s+=\s+##f", r"extra-spacing-height = #'(0 . 0)", str)2130 return str2131@rule ((2, 11, 55), "#(set-octavation oct) -> \\ottava #oct,\n\2132\\put-adjacent markup axis dir markup -> \\put-adjacent axis dir markup markup")2133def conv (str):2134 str = re.sub (r"#\(set-octavation (-*[0-9]+)\)", r"\\ottava #\1", str)2135 if re.search ('put-adjacent', str):2136 stderr_write (NOT_SMART % _ ("\\put-adjacent argument order"))2137 stderr_write (_ ("Axis and direction now come before markups:\n"))2138 stderr_write (_ ("\\put-adjacent axis dir markup markup."))2139 stderr_write ("\n")2140 return str2141@rule ((2, 11, 57), "\\center-align -> \\center-column, \\hcenter -> \\center-align")2142def conv (str):2143 str = re.sub (r"([\\:]+)center-align", r"\1center-column", str)2144 str = re.sub (r"hcenter(\s+)", r"center-align\1", str)2145 return str2146@rule ((2, 11, 60), "printallheaders -> print-all-headers")2147def conv (str):2148 str = re.sub (r"printallheaders", r"print-all-headers", str)2149 return str2150@rule ((2, 11, 61), "gregorian-init.ly -> gregorian.ly")2151def conv (str):2152 str = re.sub (r'\\include(\s+)"gregorian-init.ly"', r'\\include\1"gregorian.ly"', str)2153 return str2154@rule ((2, 11, 62), "makam-init.ly -> makam.ly, \\bigger -> \\larger")2155def conv (str):2156 str = re.sub (r'\\include(\s+)"makam-init.ly"', r'\\include\1"makam.ly"', str)2157 str = re.sub (r"([\\:])bigger", r"\1larger", str)2158 return str2159@rule ((2, 11, 64), "systemSeparatorMarkup -> system-separator-markup,\n\2160InnerStaffGroup -> StaffGroup, InnerChoirStaff -> ChoirStaff")2161def conv (str):2162 str = re.sub (r'systemSeparatorMarkup', r'system-separator-markup', str)2163 if re.search (r'\\InnerStaffGroup', str):2164 stderr_write (NOT_SMART % _("re-definition of InnerStaffGroup"))2165 stderr_write (FROM_TO % ("InnerStaffGroup", "StaffGroup"))2166 stderr_write (UPDATE_MANUALLY)2167 raise FatalConversionError ()2168 if re.search (r'\\InnerChoirStaff', str):2169 stderr_write (NOT_SMART % _("re-definition of InnerChoirStaff"))2170 stderr_write (FROM_TO % ("InnerChoirStaff", "ChoirStaff"))2171 stderr_write (UPDATE_MANUALLY)2172 raise FatalConversionError ()2173 else:2174 str = re.sub ('InnerStaffGroup', 'StaffGroup', str)2175 str = re.sub ('InnerChoirStaff', 'ChoirStaff', str)2176 return str2177@rule ((2, 12, 0),2178 _ ("Syntax changes for \\addChordShape and \\chord-shape") + "\n" + \2179 _ ("bump version for release"))2180def conv(str):2181 if re.search(r'\\addChordShape', str):2182 stderr_write (NOT_SMART % "addChordShape")2183 stderr_write (_ ("stringTuning must be added to addChordShape call.\n"))2184 stderr_write (UPDATE_MANUALLY)2185 raise FatalConversionError ()2186 if re.search (r'\\chord-shape', str):2187 stderr_write (NOT_SMART % "chord-shape")2188 stderr_write (_ ("stringTuning must be added to chord-shape call.\n"))2189 stderr_write (UPDATE_MANUALLY)2190 raise FatalConversionError ()2191 return str2192@rule ((2,12,3),2193 _ ("Remove oldaddlyrics"))2194def conv(str):2195 if re.search(r'\\oldaddlyrics', str):2196 stderr_write (NOT_SMART % "oldaddlyrics")2197 stderr_write (_ ("oldaddlyrics is no longer supported. \n \2198 Use addlyrics or lyricsto instead.\n"))2199 stderr_write (UPDATE_MANUALLY)2200 raise FatalConversionError ()2201 return str2202@rule ((2, 13, 0), _ ("keySignature property not reversed any more\n\2203MIDI 47: orchestral strings -> orchestral harp"))2204def conv(str):2205 if re.search(r'\set Staff.keySignature', str):2206 stderr_write (NOT_SMART % "Staff.keySignature")2207 stderr_write (_ ("The alist for Staff.keySignature is no \2208longer in reversed order.\n"))2209 str = str.replace('"orchestral strings"', '"orchestral harp"')2210 return str2211@rule ((2, 13, 1),2212 _ ("\\bar \".\" now produces a thick barline\n\2213ly:hairpin::after-line-breaking -> ly:spanner::kill-zero-spanned-time\n\2214Dash parameters for slurs and ties are now in dash-definition"))2215def conv(str):2216 if re.search(r'\\bar\s*"\."', str):2217 stderr_write (NOT_SMART % "\\bar \".\"")2218 stderr_write (_ ("\\bar \".\" now produces a thick barline.\n"))2219 stderr_write (UPDATE_MANUALLY)2220 str = re.sub (r'ly:hairpin::after-line-breaking', r'ly:spanner::kill-zero-spanned-time', str)2221 if re.search("(Slur|Tie)\w+#\'dash-fraction", str) \2222 or re.search("(Slur|Tie)\w+#\'dash-period", str):2223 stderr_write (NOT_SMART % "dash-fraction, dash-period")2224 stderr_write (_ ("Dash parameters for slurs and ties are now in \'dash-definition.\n"))2225 stderr_write (UPDATE_MANUALLY)2226 return str2227@rule ((2, 13, 4),2228 _ ("Autobeaming rules have changed. override-auto-beam-setting and\n\2229revert-auto-beam-setting have been eliminated.\n\2230\\overrideBeamSettings has been added.\n\2231beatGrouping has been eliminated.\n\2232Different settings for vertical layout.\n\2233ly:system-start-text::print -> system-start-text::print\n\2234Beam #'thickness -> Beam #'beam-thickness\n\2235ly:note-head::brew-ez-stencil -> note-head::brew-ez-stencil\n\2236ly:ambitus::print -> ambitus::print\n\2237Explicit dynamics context definition from `Piano centered dynamics'\n\2238template replaced by new `Dynamics' context."))2239def conv(str):2240 if re.search("override-auto-beam-setting", str):2241 stderr_write (NOT_SMART % "override-auto-beam-setting")2242 stderr_write (_ (" \2243 Autobeam settings are now overriden with \\overrideBeamSettings.\n"))2244 stderr_write (UPDATE_MANUALLY)2245 if re.search("revert-auto-beam-setting", str):2246 stderr_write (NOT_SMART % "override-auto-beam-setting")2247 stderr_write (_ (" \2248 Autobeam settings are now reverted with \\revertBeamSettings.\n"))2249 stderr_write (UPDATE_MANUALLY)2250 str = re.sub(r"\\set\s+beatGrouping", r"\\setBeatGrouping", str)2251 if re.search(r"\w+\s*.\s*beatGrouping", str):2252 stderr_write (NOT_SMART % "beatGrouping")2253 stderr_write (_ (" \2254 beatGrouping with a specified context must now be accomplished with\n\2255 \\overrideBeamSettings.\n"))2256 stderr_write (UPDATE_MANUALLY)2257 if re.search(r'alignment-offsets', str):2258 stderr_write (NOT_SMART % "alignment-offsets")2259 stderr_write (_ ("alignment-offsets has been changed to alignment-distances: \2260you must now specify the distances between staves rather than the offset of staves.\n"))2261 stderr_write (UPDATE_MANUALLY)2262 str = re.sub ('ly:(system-start-text::print|note-head::brew-ez-stencil|ambitus::print)',2263 '\\1', str)2264 str = re.sub ('(\\bBeam\\s+#\')(?=thickness\\b)', '\\1beam-', str)2265 str = re.sub (r'(\\context\s*\{{1}[^\}]+\\type\s+\"?Engraver_group\"?\s+\\name\s+"*Dynamics"*[^\}]*\}{1})',2266 '% [Convert-ly] The Dynamics context is now included by default.', str)2267 return str2268@rule ((2, 13, 10),2269 _ ("Remove obsolete engravers/translators: Note_swallow_translator,\n\2270Rest_swallow_translator, Skip_event_swallow_translator, Swallow_engraver,\n\2271Swallow_performer and String_number_engraver.\n\2272New vertical spacing variables."))2273def conv(str):2274 str = re.sub (r'\\(consists|remove)\s+"*(Swallow_(engraver|performer)|'2275 '(Note|Rest|Skip_event)_swallow_translator|String_number_engraver)"*',2276 '', str)2277 # match through the end of assignments in the form "x = 30", "x = 1 \in", or "x = #3"2278 str = re.sub (r"(page-top-space)\s*=\s*(([+-]?[.\d]*\s*\\[-\w]+)|(#?\s*[-+]?[.\d]+))",2279 r"obsolete-\g<0>"2280 r" top-system-spacing #'space = #(/ obsolete-\1 staff-space)",2281 str)2282 str = re.sub (r"(between-system-space)\s*=\s*(([+-]?[.\d]*\s*\\[-\w]+)|(#?\s*[-+]?[.\d]+))",2283 r"obsolete-\g<0>"2284 r" between-system-spacing #'space = #(/ obsolete-\1 staff-space)"2285 r" between-scores-system-spacing #'space = #(/ obsolete-\1 staff-space)",2286 str)2287 str = re.sub (r"(between-system-padding)\s*=\s*(([+-]?[.\d]*\s*\\[-\w]+)|(#?\s*[-+]?[.\d]+))",2288 r"obsolete-\g<0>"2289 r" between-system-spacing #'padding = #(/ obsolete-\1 staff-space)"2290 r" between-scores-system-spacing #'padding = #(/ obsolete-\1 staff-space)",2291 str)2292 str = re.sub (r"((before|between|after)-title-space)\s*=\s*(([+-]?[.\d]*\s*\\[-\w]+)|(#?\s*[-+]?[.\d]+))",2293 r"obsolete-\g<0>"2294 r" \2-title-spacing #'space = #(/ obsolete-\1 staff-space)",2295 str)2296 if re.search(r"VerticalAxisGroup\s*#\s*'minimum-Y-extent", str):2297 stderr_write (NOT_SMART % "minimum-Y-extent")2298 stderr_write (_ ("Vertical spacing no longer depends on the Y-extent of a VerticalAxisGroup.\n"))2299 stderr_write (UPDATE_MANUALLY)2300 return str2301@rule ((2, 13, 16),2302 _ ("Unify fetaNumber and fetaDynamic encodings"))2303def conv(str):2304 return re.sub(r'\bfeta(Number|Dynamic)', 'fetaText', str)2305@rule ((2, 13, 18),2306 _ ("\\RemoveEmpty*StaffContext -> \\*Staff \\RemoveEmptyStaves"))2307def conv(str):2308 str = re.sub (r"\\RemoveEmpty(|Drum|Rhythmic|Tab)StaffContext",2309 r"\\\1Staff \\RemoveEmptyStaves",2310 str);2311 str = re.sub (r"\\AncientRemoveEmptyStaffContext",2312 r"\\VaticanaStaff \\RemoveEmptyStaves",2313 str);2314 return str2315@rule ((2, 13, 20),2316 _ ("\\cresc etc. are now postfix operators"))2317def conv (str):2318 str = re.sub (r'\\(cresc|dim|endcresc|enddim)\b', r'\\deprecated\1', str)2319 return str2320@rule ((2, 13, 27),2321 ("interval-translate -> coord-translate"))2322def conv (str):2323 str = re.sub ('interval-translate', 'coord-translate', str)2324 return str2325@rule ((2, 13, 29),2326 _ ("Eliminate beamSettings, beatLength, \\setBeatGrouping, \\overrideBeamSettings and \\revertBeamSettings.\n\2327\"accordion.accEtcbase\" -> \"accordion.etcbass\""))2328def conv(str):2329 def sub_acc (m):2330 d = {2331 'Dot': 'dot',2332 'Discant': 'discant',2333 'Bayanbase': 'bayanbass',2334 'Stdbase': 'stdbass',2335 'Freebase': 'freebass',2336 'OldEE': 'oldEE'2337 }2338 return '"accordion.%s"' % d[m.group (1)]2339 str = re.sub (r'"accordion\.acc([a-zA-Z]+)"',2340 sub_acc, str)2341 if re.search(r'overrideBeamSettings', str):2342 stderr_write (NOT_SMART % "\\overrideBeamSettings")2343 stderr_write (_ ("Use \\set beamExceptions or \\overrideTimeSignatureSettings.\n"))2344 stderr_write (UPDATE_MANUALLY)2345 if re.search(r'revertBeamSettings', str):2346 stderr_write (NOT_SMART % "\\revertBeamSettings")2347 stderr_write (_ ("Use \\set beamExceptions or \\revertTimeSignatureSettings.\n"))2348 stderr_write (UPDATE_MANUALLY)2349 if re.search(r'beamSettings', str):2350 stderr_write (NOT_SMART % "beamSettings")2351 stderr_write (_ ("Use baseMoment, beatStructure, and beamExceptions.\n"))2352 stderr_write (UPDATE_MANUALLY)2353 if re.search(r'beatLength', str):2354 stderr_write (NOT_SMART % "beatLength")2355 stderr_write (_ ("Use baseMoment and beatStructure.\n"))2356 stderr_write (UPDATE_MANUALLY)2357 if re.search(r'setBeatGrouping', str):2358 stderr_write (NOT_SMART % "setbeatGrouping")2359 stderr_write (_ ("Use baseMoment and beatStructure.\n"))2360 stderr_write (UPDATE_MANUALLY)2361 return str2362@rule ((2, 13, 31),2363 _ ("Woodwind diagrams: Move size, thickness, and graphic from argument list to properties.\n\2364Deprecate negative dash-period for hidden lines: use #'style = #'none instead."))2365def conv(str):2366 if re.search(r'woodwind-diagram', str):2367 stderr_write (NOT_SMART % "woodwind-diagrams")2368 stderr_write (_ ("Move size, thickness, and graphic to properties. Argument should be just the key list.\n"))2369 stderr_write (UPDATE_MANUALLY)2370 str = re.sub (r"dash-period\s+=\s*#\s*-[0-9.]+",2371 r"style = #'none",2372 str);2373 return str2374@rule ((2, 13, 36),2375 _ ("Rename vertical spacing variables.\n\2376Add fretboard-table argument to savePredefinedFretboard."))2377def conv(str):2378 str = re.sub ('after-title-spacing', 'markup-system-spacing', str)2379 str = re.sub ('before-title-spacing', 'score-markup-spacing', str)2380 str = re.sub ('between-scores-system-spacing', 'score-system-spacing', str)2381 # this rule also converts page-breaking-between-system-spacing:2382 str = re.sub ('between-system-spacing', 'system-system-spacing', str)2383 str = re.sub ('between-title-spacing', 'markup-markup-spacing', str)2384 str = re.sub ('bottom-system-spacing', 'last-bottom-spacing', str)2385 str = re.sub ('top-title-spacing', 'top-markup-spacing', str)2386 str = re.sub (r"storePredefinedDiagram",2387 r"storePredefinedDiagram #default-fret-table",2388 str);2389 return str2390@rule ((2, 13, 39),2391 _ ("Rename vertical spacing grob properties."))2392def conv(str):2393 # this rule also converts default-next-staff-spacing:2394 str = re.sub ('next-staff-spacing', 'staff-staff-spacing', str)2395 # this is not a mistake:2396 # Both 'next- and 'between- become 'staff-staff-spacing.2397 # There is no conflict since they are in different grobs.2398 str = re.sub ('between-staff-spacing', 'staff-staff-spacing', str)2399 str = re.sub ('after-last-staff-spacing', 'staffgroup-staff-spacing', str)2400 str = re.sub ('inter-staff-spacing', 'nonstaff-relatedstaff-spacing', str)2401 str = re.sub ('non-affinity-spacing', 'nonstaff-unrelatedstaff-spacing', str)2402 str = re.sub ('inter-loose-line-spacing', 'nonstaff-nonstaff-spacing', str);2403 return str2404@rule ((2, 13, 40),2405 _ ("Remove \\paper variables head-separation and foot-separation."))2406def conv(str):2407 if re.search (r'head-separation', str):2408 stderr_write (NOT_SMART % "head-separation")2409 stderr_write (_ ("Adjust settings for top-system-spacing instead.\n"))2410 stderr_write (UPDATE_MANUALLY)2411 if re.search (r'foot-separation', str):2412 stderr_write (NOT_SMART % "foot-separation")2413 stderr_write (_ ("Adjust settings for last-bottom-spacing instead.\n"))2414 stderr_write (UPDATE_MANUALLY);2415 return str2416@rule ((2, 13, 42),2417 _ ("Rename space to basic-distance in various spacing alists.\n\2418Remove HarmonicParenthesesItem grob."))2419def conv(str):2420 str = re.sub (r'\(space\s+\.\s+([0-9]*\.?[0-9]*)\)', r'(basic-distance . \1)', str)2421 str = re.sub (r"#'space\s+=\s+#?([0-9]*\.?[0-9]*)", r"#'basic-distance = #\1", str)2422 if re.search (r'HarmonicParenthesesItem', str):2423 stderr_write (NOT_SMART % "HarmonicParenthesesItem")2424 stderr_write (_ ("HarmonicParenthesesItem has been eliminated.\n"))2425 stderr_write (_ ("Harmonic parentheses are part of the TabNoteHead grob.\n"))2426 stderr_write (UPDATE_MANUALLY);2427 return str2428@rule ((2, 13, 44),2429 _ ("Remove context from overrideTimeSignatureSettings and revertTimeSignatureSettings.\n"))2430def conv(str):2431 str = re.sub (r"\\(override|revert)TimeSignatureSettings(\s+[^#]*)(#[^#]*)#", r"\\\1TimeSignatureSettings\2#", str)2432 return str2433@rule ((2, 13, 46),2434 _ ("Change stringTunings from a list of semitones to a list of pitches.\n"\2435 "Change tenor and baritone ukulele names in string tunings.\n"\2436 "Generate messages for manual conversion of vertical spacing if required."))2437def conv(str):2438 def semitones2pitch(semitones):2439 steps = [0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6]2440 alterations = ["NATURAL", "SHARP", "NATURAL", "SHARP", "NATURAL", "NATURAL", "SHARP", "NATURAL", "SHARP", "NATURAL", "SHARP", "NATURAL"]2441 octave = 02442 while semitones > 11:2443 octave += 12444 semitones -=122445 while semitones < 0:2446 octave -= 12447 semitones += 122448 pitchArgs = "%d %d %s" % (octave, steps[semitones], alterations[semitones])2449 return pitchArgs2450 def convert_tones (semitone_list):2451 tones = semitone_list.split ()2452 res = ""2453 for tone in tones:2454 args = semitones2pitch(int(tone))2455 res += ",(ly:make-pitch " + args + ") "2456 return res2457 def new_tunings (matchobj):2458 return "stringTunings = #`(" + convert_tones(matchobj.group(1)) + ")"2459 str = re.sub (r"stringTunings\s*=\s*#'\(([\d\s-]*)\)", \2460 new_tunings , str)2461 str = re.sub (r"ukulele-(tenor|baritone)-tuning", r"\1-ukulele-tuning", str)2462 if re.search (r"[^-]page-top-space", str):2463 stderr_write (NOT_SMART % "page-top-space")2464 stderr_write (UPDATE_MANUALLY)2465 if re.search (r"[^-]between-system-(space|padding)", str):2466 stderr_write (NOT_SMART % "between-system-space, -padding")2467 stderr_write (UPDATE_MANUALLY)2468 if re.search (r"[^-](before|between|after)-title-space", str):2469 stderr_write (NOT_SMART % "before-, between-, after-title-space")2470 stderr_write (UPDATE_MANUALLY)2471 if re.search (r"\\name\s", str):2472 stderr_write ("\n" + _("Vertical spacing changes might affect user-defined contexts.") + "\n")2473 stderr_write (UPDATE_MANUALLY)2474 return str2475@rule ((2, 13, 48),2476 _ ("Replace bar-size with bar-extent."))2477def conv(str):2478 def size_as_extent (matchobj):2479 half = "%g" % (float (matchobj.group (1)) / 2)2480 return "bar-extent = #'(-" + half + " . " + half + ")"2481 str = re.sub (r"bar-size\s*=\s*#([0-9\.]+)", size_as_extent, str)2482 return str2483@rule ((2, 13, 51),2484 _ ("Woodwind diagrams: Changes to the clarinet diagram."))2485def conv(str):2486 if re.search (r'\\woodwind-diagram\s*#[^#]*clarinet\s', str):2487 stderr_write (NOT_SMART % "woodwind-diagrams")2488 stderr_write (_ ("Clarinet fingering changed to reflect actual anatomy of instrument.\n"))2489 stderr_write (UPDATE_MANUALLY)2490 return str2491@rule ((2, 14, 0),2492 _ ("bump version for release"))2493def conv (str):2494 return str2495@rule ((2, 15, 7),2496 _ ("Handling of non-automatic footnotes."))2497def conv(str):2498 if re.search (r'\\footnote', str):2499 stderr_write (NOT_SMART % "\\footnote")2500 stderr_write (_ ("If you are using non-automatic footnotes, make sure to set footnote-auto-numbering = ##f in the paper block.\n"))2501 stderr_write (UPDATE_MANUALLY)2502 return str2503@rule ((2, 15, 9),2504 _ ("Change in internal property for MultiMeasureRest"))2505def conv (str):2506 if re.search (r'use-breve-rest',str):2507 stderr_write (NOT_SMART % "use-breve-rest")2508 stderr_write (_ ("This internal property has been replaced by round-up-to-longer-rest, round-up-exceptions and usable-duration-logs.\n"))2509 stderr_write (UPDATE_MANUALLY)2510 return str2511@rule ((2, 15, 10),2512 _ ("Creation of a Flag grob and moving of certain Stem properties to this grob"))2513def conv (str):2514 str = re.sub (r"Stem\s+#'flag-style", r"Flag #'style", str)2515 str = re.sub (r"Stem\s+#'stroke-style", r"Flag #'stroke-style", str)2516 str = re.sub (r"Stem\s+#'flag", r"Flag #'stencil", str)2517 str = re.sub (r"(\s+(?:\\once\s*)?)\\override\s+Stem\s+#'transparent\s*=\s*##t", r"\g<1>\\override Stem #'transparent = ##t\g<1>\\override Flag #'transparent = ##t", str)2518 str = re.sub (r"(\s+(?:\\once\s*)?)\\revert\s*Stem\s+#'transparent", r"\g<1>\\revert Stem #'transparent\g<1>\\revert Flag #'transparent", str)2519 str = re.sub (r"(\s+(?:\\once\s*)?)\\override\s+Stem\s+#'stencil\s*=\s*##f", r"\g<1>\\override Stem #'stencil = ##f\g<1>\\override Flag #'stencil = ##f", str)2520 str = re.sub (r"(\s+(?:\\once\s*)?)\\revert\s*Stem\s+#'stencil", r"\g<1>\\revert Stem #'stencil\g<1>\\revert Flag #'stencil", str)2521 return str2522@rule ((2, 15, 16), r"\makeStringTuning, \contextStringTuning -> \stringTuning")2523def conv (str):2524 str = re.sub (r"(\s+)\\contextStringTuning(\s+)#'([-a-zA-Z]+)(\s+<[^<>]+>)",2525 r"""\g<1>#(define \g<3> #{ \\stringTuning\g<4> #})\g<1>\\set stringTunings = #\g<3>""",2526 str)2527 str = re.sub (r"""2528\\makeStringTuning(\s+)#'([-a-zA-Z]+)""",2529 r"""2530"\g<2>" = \\stringTuning""", str)2531 str = re.sub (r"\\makeStringTuning(\s+)#'([-a-zA-Z]+)(\s+<[^<>]+>)",2532 r"#(define \g<2> #{ \\stringTuning\g<3> #})", str)2533 return str2534@rule ((2, 15, 17), "\\markuplines -> \\markuplist\n\2535Change Beam broken slope syntax.")2536def conv (str):2537 str = re.sub (r"""2538\\markuplines( +)([^ ].*)2539 \1([^ ])""", r"""2540\\markuplist\g<1>\g<2>2541 \g<1>\g<3>""", str)2542 str = re.sub (r"\\markuplines", r"\\markuplist", str)2543 str = re.sub (r"@funindex markuplines", r"@funindex markuplist", str)2544 if re.search (r'consistent-broken-slope', str):2545 stderr_write (NOT_SMART % "consistent-broken-slope")2546 stderr_write (_ ("consistent-broken-slope is now handled through the positions callback.\n"))2547 stderr_write (_ ("input/regression/beam-broken-classic.ly shows how broken beams are now handled.\n"))2548 stderr_write (UPDATE_MANUALLY)2549 return str2550def paren_matcher (n):2551 # poor man's matched paren scanning, gives up2552 # after n+1 levels. Matches any string with balanced2553 # parens inside; add the outer parens yourself if needed.2554 # Nongreedy.2555 return r"[^()]*?(?:\("*n+r"[^()]*?"+r"\)[^()]*?)*?"*n2556 return2557def undollar_scm (m):2558 return re.sub (r"\$(.?)", r"\1", m.group (0))2559def undollar_embedded (m):2560 str = re.sub (r"#\$", "#", m.group (1))2561 # poor man's matched paren scanning after #, gives up2562 # after 25 levels.2563 str = re.sub ("#`?\("+paren_matcher (25)+"\)", undollar_scm, str)2564 return m.string[m.start (0):m.start (1)] + str + m.string[m.end (1):m.end (0)]2565def strip_export (str):2566 return re.sub (r"\(ly:export\s+(" + paren_matcher (25) + r")\)",2567 r"\1", str)2568def export_puller (m):2569 if not re.search (r"ly:export\s+", m.group (0)):2570 return m.group (0)2571 return "$" + strip_export (m.string[m.start (0)+1:m.end (0)])2572def ugly_function_rewriter (m):2573 return m.string[m.start(0):m.start(1)] + strip_export (m.group (1)) + m.string[m.end(1):m.end(0)]2574should_really_be_music_function = "(?:\2575set-time-signature|empty-music|add-grace-property|\2576remove-grace-property|set-accidental-style)"2577def record_ugly (m):2578 global should_really_be_music_function2579 if not re.match (should_really_be_music_function, m.group (1)) \2580 and re.search (r"ly:export\s+", m.group (2)):2581 should_really_be_music_function = \2582 should_really_be_music_function[:-1] + "|" + m.group (1) + ")"2583 return m.group (0)2584@rule ((2, 15, 18), "#$ -> #, ly:export -> $")2585def conv (str):2586 str = re.sub (r"(?s)#@?\{(.*?)#@?\}", undollar_embedded, str)2587 str = re.sub (r"#\(define(?:-public)?\s+\(([-a-zA-Z]+)"2588 + r"\b[^()]*?\)(" + paren_matcher (25)2589 + r")\)", record_ugly, str)2590 str = re.sub (r"\(define(?:-public)?\s+\(" + should_really_be_music_function2591 + r"\b[^()]*\)(" + paren_matcher (25)2592 + r")\)", ugly_function_rewriter, str)2593 str = re.sub (r"#(?=\(" + should_really_be_music_function + ")", "$", str)2594 str = re.sub (r"#\(markup\*(?=\s)", r"$(markup", str)2595 str = re.sub ("#\("+paren_matcher (25)+"\)", export_puller, str)2596 if re.search (r"\(ly:export\s+", str):2597 stderr_write (NOT_SMART % "ly:export")2598 return str2599@rule ((2, 15, 19), r"$(set-time-signature ...) -> \time")2600def conv (str):2601 str = re.sub (r"\$\(set-time-signature\s+([0-9]+)\s+([0-9]+)\s*\)",2602 r"\\time \1/\2", str)2603 str = re.sub (r"\$\(set-time-signature\s+([0-9]+)\s+([0-9]+)\s+(" +2604 paren_matcher (5) + r")\)", r"\\time #\3 \1/\2", str)2605 if re.search (r"\(set-time-signature\s+", str):2606 stderr_write (NOT_SMART % "set-time-signature")2607 return str2608@rule ((2, 15, 20), r"$(set-accidental-style ...) -> \accidentalStyle")2609def conv (str):2610 str = re.sub (r"\$\(set-accidental-style\s+'([-a-z]+)\)",2611 r'\\accidentalStyle "\1"', str)2612 str = re.sub (r"\$\(set-accidental-style\s+'([-a-z]+)\s+'([-A-Za-z]+)\s*\)",2613 r'''\\accidentalStyle #'\2 "\1"''', str)2614 str = re.sub (r"(@funindex\s+)set-accidental-style",2615 r"\1\\accidentalStyle", str)2616 return str2617def brace_matcher (n):2618 # poor man's matched brace scanning, gives up2619 # after n+1 levels. Matches any string with balanced2620 # braces inside; add the outer braces yourself if needed.2621 # Nongreedy.2622 return r"[^{}]*?(?:{"*n+r"[^{}]*?"+r"}[^{}]*?)*?"*n2623matchstring = r'"(?:[^"\\]|\\.)*"'2624matcharg = (r"\s+(?:[$#]['`]?\s*(?:[a-zA-Z][^ \t\n()\\]*|" + matchstring2625 + r"|#?\(" + paren_matcher(20) + r"\)|"2626 + r"-?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)|"2627 + r"#(?:[tf]|\\.|@?\{" + brace_matcher (10) + r"#@?\}))|"2628 + matchstring + r"|\\[a-z_A-Z]+|[0-9]+(?:/[0-9]+)?|-[0-9]+)")2629matchmarkup = (r'(?:\\markup\s*(?:@?\{' + brace_matcher (20) +r'\}|' +2630 matchstring + r'|(?:\\[a-z_A-Z][a-z_A-Z-]*(?:' + matcharg +2631 r')*?\s*)*(?:' + matchstring + r"|@?\{" + brace_matcher (20) +2632 r"\}))|" + matchstring + ")")2633@rule((2, 15, 25), r"\(auto)?Footnote(Grob)? -> \footnote")2634def conv (str):2635 # The following replacement includes the final markup argument in2636 # the match in order to better avoid touching the equally named2637 # markup function. The other functions have unique names, so2638 # there is no point in including their last, possibly complex2639 # argument in the match.2640 str = re.sub (r"\\footnote(" + matcharg + (r")(\s*" + matchmarkup)*2 + ")",2641 r"\\footnote\2\1\3", str)2642 str = re.sub (r"\\footnoteGrob"+("(" + matcharg + ")")*2 + r"(\s*" + matchmarkup + ")",2643 r"\\footnote\3\2\1", str)2644 str = re.sub (r"\\autoFootnoteGrob" + ("(" + matcharg + ")")*2,2645 r"\\footnote\2\1", str)2646 str = re.sub (r"\\autoFootnote",2647 r"\\footnote", str)2648 return str2649@rule((2, 15, 32), r"tempoWholesPerMinute -> \tempo")2650def conv (str):2651 def sub_tempo (m):2652 num = int (m.group (1))2653 den = int (m.group (2))2654 if (den & (den - 1)) != 0 :2655 return m.group (0)2656 # Don't try dotted forms if they result in less than 30 bpm.2657 # It is not actually relevant to get this right since this2658 # only occurs in non-printing situations2659 if den >= 16 and (num % 7) == 0 and num >= 210 :2660 return r"\tempo %d.. = %d" % (den/4, num/7)2661 if den >= 8 and (num % 3) == 0 and num >= 90 :2662 return r"\tempo %d. = %d" % (den/2, num/3)2663 return r"\tempo %d = %d" % (den, num)2664 str = re.sub (r"\\context\s*@?\{\s*\\Score\s+tempoWholesPerMinute\s*=\s*" +2665 r"#\(ly:make-moment\s+([0-9]+)\s+([0-9]+)\)\s*@?\}",2666 sub_tempo, str)2667 return str2668@rule((2, 15, 39), r"\footnote ... -> \footnote ... \default")2669def conv (str):2670 def not_first (s):2671 def match_fun (m):2672 if m.group (1):2673 return m.group (0)2674 return m.expand (s)2675 return match_fun2676 str = re.sub ("(" + matchmarkup + ")|"2677 + r"(\\footnote(?:\s*"2678 + matchmarkup + ")?" + matcharg + "(?:" + matcharg2679 + ")?\s+" + matchmarkup + ")",2680 not_first (r"\2 \\default"), str)2681 return str2682@rule ((2, 15, 40), r"Remove beamWholeMeasure")2683def conv (str):2684 if re.search (r"\bbeamWholeMeasure\b", str):2685 stderr_write (NOT_SMART % "beamWholeMeasure")2686 stderr_write (_ ("beamExceptions controls whole-measure beaming.") + "\n")2687 return str2688@rule ((2, 15, 42), r"\set stringTuning -> \set Staff.stringTuning")2689def conv (str):2690 str = re.sub (r"(\\set\s+)stringTuning", r"\1Staff.stringTuning", str)2691 return str2692wordsyntax = r"[a-zA-Z\200-\377](?:[-_]?[a-zA-Z\200-\377])*"2693@rule ((2, 15, 43), r'"custom-tuning" = -> custom-tuning =')2694def conv (str):2695 str = re.sub ('\n"(' + wordsyntax + r')"(\s*=\s*\\stringTuning)', "\n\\1\\2", str)2696 return str2697@rule ((2, 16, 0),2698 _ ("bump version for release"))2699def conv (str):2700 return str2701@rule ((2, 17, 0), r"blank-*-force -> blank-*-penalty")2702def conv (str):2703 str = re.sub ('blank-page-force', 'blank-page-penalty', str)2704 str = re.sub ('blank-last-page-force', 'blank-last-page-penalty', str)2705 str = re.sub ('blank-after-score-page-force', 'blank-after-score-page-penalty', str)2706 return str2707@rule ((2, 17, 4), r"\shape Grob #offsets -> \shape #offsets Grob")2708def conv (str):2709 str = re.sub (r"\\shape(\s+(?:[a-zA-Z]+|" + matchstring + "))(" +2710 matcharg + ")", r"\\shape\2\1", str)2711 return str2712barstring=r"(\\bar|whichBar|defaultBarType|segnoType|doubleRepeatType|startRepeatType|endRepeatType|doubleRepeatSegnoType|startRepeatSegnoType|endRepeatSegnoType)(\s*[=]?\s*[#]?)"2713@rule ((2, 17, 5), r"New bar line interface")2714def conv(str):2715 str = re.sub (barstring + r'"\|:"', '\\1\\2".|:"', str)2716 str = re.sub (barstring + r'":\|"', '\\1\\2":|."', str)2717 str = re.sub (barstring + r'"\|\|:"', '\\1\\2".|:-||"', str)2718 str = re.sub (barstring + r'":\|:"', '\\1\\2":..:"', str)2719 str = re.sub (barstring + r'"\.\|\."', '\\1\\2".."', str)2720 str = re.sub (barstring + r'"\|S"', '\\1\\2"S-|"', str)2721 str = re.sub (barstring + r'"S\|"', '\\1\\2"S-S"', str)2722 str = re.sub (barstring + r'":\|S"', '\\1\\2":|.S"', str)2723 str = re.sub (barstring + r'":\|S\."', '\\1\\2":|.S-S"', str)2724 str = re.sub (barstring + r'"S\|:"', '\\1\\2"S.|:-S"', str)2725 str = re.sub (barstring + r'"\.S\|:"', '\\1\\2"S.|:"', str)2726 str = re.sub (barstring + r'":\|S\|:"', '\\1\\2":|.S.|:"', str)2727 str = re.sub (barstring + r'":\|S\.\|:"', '\\1\\2":|.S.|:-S"', str)2728 str = re.sub (barstring + r'":"', '\\1\\2";"', str)2729 str = re.sub (barstring + r'"\|s"', '\\1\\2"|-s"', str)2730 str = re.sub (barstring + r'"dashed"', '\\1\\2"!"', str)2731 str = re.sub (barstring + r'"kievan"', '\\1\\2"k"', str)2732 str = re.sub (barstring + r'"empty"', '\\1\\2"-"', str)2733 return str2734symbol_list = (r"#'(?:" + wordsyntax + r"|\(\s*(?:" + wordsyntax + r"\s+)*"2735 + wordsyntax + r"\s*\))")2736grob_path = r"(?:" + symbol_list + r"\s+)*" + symbol_list2737grob_spec = wordsyntax + r"(?:\s*\.\s*" + wordsyntax + r")?"2738def path_replace (m):2739 return m.group (1) + string.join (re.findall (wordsyntax, m.group (2)), ".")2740@rule ((2, 17, 6), r"""\accidentalStyle #'Context "style" -> \accidentalStyle Context.style2741\alterBroken "Context.grob" -> \alterBroken Context.grob2742\overrideProperty "Context.grob" -> \overrideProperty Context.grob2743\tweak Grob #'symbol -> \tweak Grob.symbol""")2744def conv (str):2745 def patrep (m):2746 def fn_path_replace (m):2747 x = string.join (re.findall (wordsyntax, m.group (2)), ".")2748 if x in ["TimeSignature", "KeySignature", "BarLine",2749 "Clef", "StaffSymbol", "OttavaBracket",2750 "LedgerLineSpanner"]:2751 x = "Staff." + x2752 return m.group (1) + x2753 if m.group (1):2754 return m.group (0)2755 x = m.group (2) + m.group (4)2756 if m.group (3):2757 x = x + re.sub (r"(\s*)(" + symbol_list + ")", fn_path_replace,2758 m.group (3))2759 if not m.group (5):2760 x = r"\single" + x2761 return x2762 str = re.sub (r'''(\\accidentalStyle\s+)#?"([-A-Za-z]+)"''',2763 r"\1\2", str)2764 str = re.sub (r'''(\\accidentalStyle\s+)#'([A-Za-z]+)\s+#?"?([-A-Za-z]+)"?''',2765 r"\1\2.\3", str)2766 str = re.sub (r'''(\\(?:alterBroken|overrideProperty)\s+)#?"([A-Za-z]+)\s*\.\s*([A-Za-z]+)"''',2767 r"\1\2.\3", str)2768 str = re.sub (r'''(\\tweak\s+)#?"?([A-W][A-Za-z]*)"?\s+?#'([a-zX-Z][-A-Za-z]*)''',2769 r"\1\2.\3", str)2770 str = re.sub (r'''(\\tweak\s+)#'([a-zX-Z][-A-Za-z]*)''',2771 r"\1\2", str)2772 str = re.sub ("(" + matchmarkup + ")|"2773 + r"(\\footnote(?:\s*"2774 + matchmarkup + ")?" + matcharg + ")(" + matcharg2775 + r")?(\s+" + matchmarkup + r")(\s+\\default)?",2776 patrep, str)2777 str = re.sub (r'''(\\alterBroken)(\s+[A-Za-z.]+)(''' + matcharg2778 + matcharg + ")", r"\1\3\2", str)2779 str = re.sub (r"(\\overrideProperty\s+)(" + grob_spec + r"\s+" + grob_path + ")",2780 path_replace, str)2781 str = re.sub (r"(\\(?:override|revert)\s+)(" + grob_spec + r"\s+" + grob_path + ")",2782 path_replace, str)2783 return str2784@rule ((2, 17, 11), r"""\times -> \tuplet, \set tupletSpannerDuration -> \tupletSpan2785(ly:make-moment 1 4) -> (ly:make-moment 1/4)2786(ly:make-duration 0 0 1 2) -> (ly:make-duration 0 0 1/2)""")2787def conv(str):2788 def sub_dur (m):2789 num = int (m.group (1))2790 den = int (m.group (2))2791# if den is no power of 2, don't even try to use an unscaled duration2792 if (den & (den - 1)) != 0 :2793 return (r"\tupletSpan 1*%d/%d" % (num, den))2794 if den >= 4 and num == 7 :2795 return (r"\tupletSpan %d.." % (den/4))2796 if den >= 2 and num == 3 :2797 return (r"\tupletSpan %d." % (den/2))2798 if num == 1 :2799 return (r"\tupletSpan %d" % den)2800 return (r"\tupletSpan 1*%d/%d" % (num, den))2801 str = re.sub (r"\\set\s+tupletSpannerDuration\s*=\s*" +2802 r"#\(ly:make-moment\s+([0-9]+)\s+([0-9]+)\s*\)",2803 sub_dur, str)2804 str = re.sub (r"\\unset tupletSpannerDuration",2805 r"\\tupletSpan \\default", str)2806 str = re.sub (r"\\times(\s*)([0-9]+)/([0-9]+)",2807 r"\\tuplet\1\3/\2", str)2808 str = re.sub (r"(\(ly:make-moment\s+-?[0-9]+)\s+([1-9][0-9]*\))",2809 r"\1/\2", str)2810 str = re.sub (r"(\(ly:make-moment\s+-?[0-9]+)\s+([0-9]+\s+-?[0-9]+)\s([0-9]+\))",2811 r"\1/\2/\3", str)2812 str = re.sub (r"(\(ly:make-duration\s+-?[0-9]+\s+[0-9]+\s+[0-9]+)\s+([0-9]+\))",2813 r"\1/\2", str)2814 return str2815@rule((2, 17, 14), r"\accepts ... -> \accepts ... \defaultchild ...")2816def conv(str):2817 def matchaccepts(m):2818 # First weed out definitions starting from an existing2819 # definition: we assume that the inherited \defaultchild is2820 # good enough for our purposes. Heuristic: starts with a2821 # backslash and an uppercase letter.2822 if re.match (r"\s*\\[A-Z]", m.group (1)):2823 return m.group (0)2824 # existing defaultchild obviously trumps all2825 if re.search (r"\\defaultchild[^-_a-zA-Z]", m.group (1)):2826 return m.group (0)2827 # take the first \\accepts if any and replicate it2828 return re.sub ("(\r?\n[ \t]*|[ \t]+)"2829 + r"""\\accepts(\s+(?:#?".*?"|[-_a-zA-Z]+))""",2830 r"\g<0>\1\\defaultchild\2",2831 m.group (0), 1)2832 str = re.sub (r"\\context\s*@?\{(" + brace_matcher (20) + ")\}",2833 matchaccepts, str)2834 return str2835@rule((2, 17, 15), r"""#(ly:set-option 'old-relative)2836\relative -> \relative c'""")2837def conv(str):2838 if re.search (r"[#$]\(ly:set-option\s+'old-relative", str):2839 stderr_write (NOT_SMART % "#(ly:set-option 'old-relative)")2840 stderr_write (UPDATE_MANUALLY)2841 raise FatalConversionError ();2842 # If the file contains a language switch to a language where the2843 # name of c is not "c", we can't reliably know which parts of the2844 # file will need "c" and which need "do".2845 m = re.search (r'\\language\s(?!\s*#?"(?:nederlands|deutsch|english|norsk|suomi|svenska))"', str)2846 if m:2847 # Heuristic: if there is a non-commented { before the language2848 # selection, we can't be sure.2849 # Also if there is any selection of a non-do language.2850 if (re.search ("^[^%\n]*\\{", m.string[:m.start()], re.M)2851 or re.search ('\\language\s(?!\s*#?"(?:catalan|espanol|español|italiano|français|portugues|vlaams))"', str)):2852 do = "$(ly:make-pitch 0 0)"2853 else:2854 do = "do'"2855 else:2856 do = "c'"2857 str = re.sub (r"(\\relative)(\s+(\{|[\\<]))",2858 r"\1 " + do + r"\2", str)2859 return str2860@rule ((2, 17, 18),2861 "Rename OctavateEight to ClefModifier, rename related properties.")2862def conv(str):2863 str = re.sub ('OctavateEight', 'ClefModifier', str)2864 str = re.sub ('octavate-eight-interface', 'clef-modifier-interface', str)2865 str = re.sub ('clefOctavation', 'clefTransposition', str)2866 str = re.sub ('clefOctavationFormatter', 'clefTranspositionFormatter', str)2867 str = re.sub ('clefOctavationStyle', 'clefTranspositionStyle', str)2868 str = re.sub ('cueClefOctavation', 'cueClefTransposition', str)2869 str = re.sub ('cueClefOctavationFormatter', 'cueClefTranspositionFormatter', str)2870 str = re.sub ('cueClefOctavationStyle', 'cueClefTranspositionStyle', str)2871 return str2872@rule((2, 17, 19), r"\column { \vspace #2 } -> \column { \combine \null \vspace #2 }")2873def conv(str):2874 def vspace_replace(m):2875# vspace now always adds space and does not, for example, change the2876# impact of either baselineskip or descenders on the line above.2877#2878# We can't simulate the old behavior in a simpler manner. A command2879# of its own is not really warranted since this behavior combines2880# badly enough with other spacing considerations (like baselineskip2881# and descenders) as to make it not all that useful. So this2882# conversion rule is here more for compatibility's sake rather than2883# preserving desirable behavior.2884 str = re.sub (r"(\\\\?)vspace(\s)", r"\1combine \1null \1vspace\2", m.group(0))2885 return str2886 str = re.sub (r"\\(?:left-|right-|center-|)column\s*\{" + brace_matcher (20) + r"\}",2887 vspace_replace, str)2888 return str2889@rule((2, 17, 20), _(r"Flag.transparent and Flag.color inherit from Stem"))2890def conv(str):2891 str = re.sub (r"(((?:\\once\s*)?)\\override\s+((?:\w+\.)?)Stem\.(transparent|color)\s*=\s*(#\S+))\s+\2\\override\s+\3Flag\.\4\s*=\s*\5",2892 r"\1", str)2893 str = re.sub (r"(((?:\\once\s*)?)\\revert\s+((?:\w+\.)?)Stem\.(transparent|color))\s+\2\\revert\s+\3Flag\.\4",2894 r"\1", str)2895 str = re.sub (r"(\\tweak\s+((?:\w+\.)?)Stem\.(transparent|color)\s+(#\S+))\s+\\tweak\s+\2Flag\.\3\s+\4",2896 r"\1", str)2897 return str2898@rule((2, 17, 25), r'''\tempo 4. = 50~60 -> \tempo 4. = 50-602899-| -> -!2900pipeSymbol, escapedParenthesisOpenSymbol ... -> "|", "\\(" ...''')2901def conv(str):2902# This goes for \tempo commands ending with a range, like2903# = 50 ~ 602904# and uses - instead. We don't explicitly look for \tempo since the2905# complete syntax has a large number of variants, and this is quite2906# unlikely to occur in other contexts2907 str = re.sub (r"(=\s*[0-9]+\s*)~(\s*[0-9]+\s)", r"\1-\2", str)2908# Match strings, and articulation shorthands that end in -^_2909# so that we leave alone -| in quoted strings and c4--|2910 def subnonstring(m):2911 if m.group (1):2912 return m.group (1)+"!"2913 return m.group (0)2914 str = re.sub (r"([-^_])\||" + matchstring + r"|[-^_][-^_]", subnonstring, str)2915 str = re.sub (r"\bdashBar\b", "dashBang", str)2916 orig = [ "pipeSymbol",2917 "bracketOpenSymbol",2918 "bracketCloseSymbol",2919 "tildeSymbol",2920 "parenthesisOpenSymbol",2921 "parenthesisCloseSymbol",2922 "escapedExclamationSymbol",2923 "escapedParenthesisOpenSymbol",2924 "escapedParenthesisCloseSymbol",2925 "escapedBiggerSymbol",2926 "escapedSmallerSymbol" ]2927 repl = [ r'"|"',2928 r'"["',2929 r'"]"',2930 r'"~"',2931 r'"("',2932 r'")"',2933 r'"\\!"',2934 r'"\\("',2935 r'"\\)"',2936 r'"\\>"',2937 r'"\\<"']2938 words = r"\b(?:(" + ")|(".join (orig) + r"))\b"2939 def wordreplace(m):2940 def instring(m):2941 return re.sub (r'["\\]',r'\\\g<0>',repl[m.lastindex-1])2942 if m.lastindex:2943 return repl[m.lastindex-1]2944 return '"' + re.sub (words, instring, m.group(0)[1:-1]) + '"'2945 str = re.sub (words + "|" + matchstring, wordreplace, str)2946 return str2947@rule((2, 17, 27), r'''\stringTuning \notemode -> \stringTuning''')2948def conv(str):2949 str = re.sub (r"\\stringTuning\s*\\notemode(\s*)@?\{\s*(.*?)\s*@?\}",2950 r"\\stringTuning\1\2", str)2951 if re.search (r'[^-\w]staff-padding[^-\w]', str):2952 stderr_write (NOT_SMART % "staff-padding")2953 stderr_write (_ ("Staff-padding now controls the distance to the baseline, not the nearest point."))2954 return str2955@rule((2, 17, 29), r'''Dynamic_engraver -> New_dynamic_engraver+Dynamic_align_engraver2956New_dynamic_engraver -> Dynamic_engraver''')2957def conv(str):2958 str = re.sub ("(\r?\n?[ \t]*\\\\(?:consists|remove)\\s*)(\"?)Dynamic_engraver\\2",2959 r"\1\2New_dynamic_engraver\2\1\2Dynamic_align_engraver\2",2960 str)2961# Should we warn about any remaining Dynamic_engraver? Possibly it2962# will do the job just fine.2963 str = re.sub ("New_dynamic_engraver", "Dynamic_engraver", str)2964 return str2965@rule ((2, 17, 97), r'''(make-relative (a b) b ...) -> make-relative (a b) #{ a b #}...''')2966def conv (str):2967 str = re.sub (r"(\(make-relative\s+\(\s*(([A-Za-z][-_A-Za-z0-9]*)" +2968 r"(?:\s+[A-Za-z][-_A-Za-z0-9]*)*)\s*\)\s*)\3(?=\s)",2969 r"\1(make-event-chord (list \2))", str)2970 str = re.sub (r"(\(make-relative\s+\(\s*([A-Za-z][-_A-Za-z0-9]*" +2971 r"(?:\s+([A-Za-z][-_A-Za-z0-9]*))+)\s*\)\s*)\3(?=\s)",2972 r"\1(make-sequential-music (list \2))", str)2973 return str2974@rule ((2, 18, 0),2975 _ ("bump version for release"))2976def conv (str):2977 return str2978@rule ((2, 19, 2), r"\lyricsto \new/\context/... -> \new/\context/... \lyricsto")2979def conv (str):2980 word=r'(?:#?"[^"]*"|\b' + wordsyntax + r'\b)'2981 str = re.sub (r"(\\lyricsto\s*" + word + r"\s*)(\\(?:new|context)\s*" + word2982 + r"(?:\s*=\s*" + word + r")?\s*)",2983 r"\2\1", str)2984 str = re.sub (r"(\\lyricsto\s*" + word + r"\s*)\\lyricmode\b\s*",2985 r"\1", str)2986 str = re.sub (r"(\\lyricsto\s*" + word + r"\s*)\\lyrics\b\s*",2987 r"\\new Lyrics \1", str)2988 str = re.sub (r'\\lyricmode\s*(\\lyricsto\b)', r"\1", str)2989 return str2990@rule ((2, 19, 7), "keySignature -> keyAlterations")2991def conv(str):2992 str = re.sub (r'\bkeySignature\b', 'keyAlterations', str)2993 str = re.sub (r'\blastKeySignature\b', 'lastKeyAlterations', str)2994 str = re.sub (r'\blocalKeySignature\b', 'localAlterations', str)2995 return str2996@rule ((2, 19, 11), "thin-kern -> segno-kern")2997def conv(str):2998 str = re.sub (r'\bthin-kern\b', 'segno-kern', str)2999 return str3000# before_id is written in a manner where it will only substantially3001# (rather than as a lookbefore assertion) match material that could3002# not be part of a previous id. In that manner, one replacement does3003# not inhibit an immediately adjacent replacement.3004before_id = r'(?:^|(?<!\\)(?:\\\\)+|(?<=[^-_\\a-zA-Z])|(?<=[^a-zA-Z][-_]))'3005# after_id is a pure lookbehind assertion so its match string is3006# always empty3007after_id = r'(?![a-zA-Z]|[-_][a-zA-Z])'3008@rule ((2, 19, 16), """implicitTimeSignatureVisibility -> initialTimeSignatureVisibility3009csharp -> c-sharp""")3010def conv(str):3011 str = re.sub (r'\bimplicitTimeSignatureVisibility\b', 'initialTimeSignatureVisibility', str)3012 str = re.sub ('(' + before_id + r'[a-g])((?:sharp){1,2}|(?:flat){1,2})'3013 + after_id, r'\1-\2', str)3014 return str3015@rule ((2, 19, 22), """whiteout -> whiteout-box3016(define-xxx-function (parser location ...) -> (define-xxx-function (...)3017(xxx ... parser ...) -> (xxx ... ...)""")3018def conv(str):3019 # whiteout -> whiteout-box3020 str = re.sub (r"\\whiteout(?![a-z_-])", r"\\whiteout-box", str)3021 str = re.sub (r"\b\.whiteout(?![a-z_-])\b", r".whiteout-box", str)3022 str = re.sub (r"#'whiteout(?![a-z_-])\b", r"#'whiteout-box", str)3023 str = re.sub (r"\bstencil-whiteout\b", r"stencil-whiteout-box", str)3024 3025 # (define-xxx-function (parser location ...) -> (define-xxx-function (...)3026 def subst(m):3027 def subsub(m):3028 str = (m.group (1)3029 + re.sub ('(?<=\s|["\\()])' + m.group (2) + r'(?=\s|["\\()])',3030 r'(*location*)',3031 re.sub (r'(?<=\s|["\\()])parser(?=\s|["\\()])',3032 r'(*parser*)', m.group (3))))3033 return str3034 return re.sub (r'(\([-a-z]+\s*\(+)parser\s+([-a-z]+)\s*((?:.|\n)*)$',3035 subsub, m.group (0))3036 str = re.sub (r'\(define-(?:music|event|scheme|void)-function(?=\s|["(])'3037 + paren_matcher (20) + r'\)', subst, str)3038 # (xxx ... parser ...) -> (xxx ... ...)3039 def repl (m):3040 return m.group (1) + inner (m.group (2))3041 def inner (str):...

Full Screen

Full Screen

MarkerPrinter.py

Source:MarkerPrinter.py Github

copy

Full Screen

1#!/usr/bin/env python32# SPDX-License-Identifier: BSD-3-Clause3#4# Copyright (c) 2019, Josh Chien. All rights reserved.5from argparse import ArgumentParser6import numpy as np7from PIL import Image8import io9import warnings10import os11import cairo12from cairosvg import svg2png13import math14import tempfile15def SaveArucoDictBytesList(filePath = "arucoDictBytesList.npz"):16 import numpy as np17 # cv2 is optional dependency18 try:19 import cv220 from cv2 import aruco21 # Name, Flag22 dictInfo = \23 [24 ("DICT_4X4_1000", aruco.DICT_4X4_1000),25 ("DICT_5X5_1000", aruco.DICT_5X5_1000),26 ("DICT_6X6_1000", aruco.DICT_6X6_1000),27 ("DICT_7X7_1000", aruco.DICT_7X7_1000),28 ("DICT_ARUCO_ORIGINAL", aruco.DICT_ARUCO_ORIGINAL),29 ("DICT_APRILTAG_16h5", aruco.DICT_APRILTAG_16h5),30 ("DICT_APRILTAG_25h9", aruco.DICT_APRILTAG_25h9),31 ("DICT_APRILTAG_36h10", aruco.DICT_APRILTAG_36h10),32 ("DICT_APRILTAG_36h11", aruco.DICT_APRILTAG_36h11),33 ]34 arucoDictBytesList = {}35 for name, flag in dictInfo:36 arucoDict = aruco.Dictionary_get(flag)37 arucoDictBytesList[name] = arucoDict.bytesList38 np.savez_compressed(filePath, **arucoDictBytesList)39 return arucoDictBytesList40 except Exception as e:41 warnings.warn(str(e))42 return None43 return None44class MarkerPrinter:45 debugMode = None # "LINE" "BLOCK"46 # Static Vars47 # SVG https://oreillymedia.github.io/Using_SVG/guide/units.html48 # for PDF and SVG, 1 pixel = 1/72 inch, 1 cm = 1/2.54 inch, 1pixl = 2.54/72 cm, 1cm = 72/2.54 pixels49 ptPerMeter = 72 / 2.54 * 10050 surface = {51 ".SVG": cairo.SVGSurface,52 ".PDF": cairo.PDFSurface,53 ".PS": cairo.PSSurface }54 if (os.path.isfile("arucoDictBytesList.npz")):55 arucoDictBytesList = np.load("arucoDictBytesList.npz")56 else:57 warnings.warn("Missing build-in arucoDictBytesList.npz, generate it again")58 arucoDictBytesList = SaveArucoDictBytesList(filePath = "arucoDictBytesList.npz")59 arucoDictMarkerSize = \60 {61 "DICT_4X4_1000": 4,62 "DICT_5X5_1000": 5,63 "DICT_6X6_1000": 6,64 "DICT_7X7_1000": 7,65 "DICT_ARUCO_ORIGINAL": 5,66 "DICT_APRILTAG_16h5": 4,67 "DICT_APRILTAG_25h9": 5,68 "DICT_APRILTAG_36h10": 6,69 "DICT_APRILTAG_36h11": 6,70 }71 def ArucoBits(dictionary, markerID):72 bytesList = MarkerPrinter.arucoDictBytesList[dictionary][markerID].ravel()73 markerSize = MarkerPrinter.arucoDictMarkerSize[dictionary]74 arucoBits = np.zeros(shape = (markerSize, markerSize), dtype = bool)75 base2List = np.array( [128, 64, 32, 16, 8, 4, 2, 1], dtype = np.uint8)76 currentByteIdx = 077 currentByte = bytesList[currentByteIdx]78 currentBit = 079 for row in range(markerSize):80 for col in range(markerSize):81 if(currentByte >= base2List[currentBit]):82 arucoBits[row, col] = True83 currentByte -= base2List[currentBit]84 currentBit = currentBit + 185 if(currentBit == 8):86 currentByteIdx = currentByteIdx + 187 currentByte = bytesList[currentByteIdx]88 if(8 * (currentByteIdx + 1) > arucoBits.size):89 currentBit = 8 * (currentByteIdx + 1) - arucoBits.size90 else:91 currentBit = 0;92 return arucoBits93 def __DrawBlock(context,94 dictionary = None, markerLength = None, borderBits = 1,95 chessboardSize = (1, 1), squareLength = None, firstMarkerID = 0,96 blockX = 0, blockY = 0, originX = 0, originY = 0, pageBorderX = 0, pageBorderY = 0,97 mode = "CHESS" ):98 if(squareLength is None):99 squareLength = markerLength100 if(markerLength is None):101 markerLength = squareLength102 if((squareLength is None) or (markerLength is None)):103 raise ValueError("lenght is None")104 dawMarkerBlock = False105 if ((mode == "ARUCO") or (mode == "ARUCOGRID")):106 dawMarkerBlock = True107 elif(chessboardSize[1] % 2 == 0):108 dawMarkerBlock = (( blockX % 2 == 0 ) == ( blockY % 2 == 0 ))109 else:110 dawMarkerBlock = (( blockX % 2 == 0 ) != ( blockY % 2 == 0 ))111 if(dawMarkerBlock):112 if (mode != "CHESS"):113 if(dictionary is None):114 raise ValueError("dictionary is None")115 if (mode == "CHARUCO"):116 originX = (blockX - originX) * squareLength + (squareLength - markerLength)*0.5 + pageBorderX117 originY = (blockY - originY) * squareLength + (squareLength - markerLength)*0.5 + pageBorderY118 else:119 originX = (blockX - originX) * squareLength + pageBorderX120 originY = (blockY - originY) * squareLength + pageBorderY121 context.set_source_rgba(0.0, 0.0, 0.0, 1.0)122 context.rectangle(originX, originY, markerLength, markerLength)123 context.fill()124 # Generate marker125 if (mode == "CHARUCO"):126 markerID = firstMarkerID + (blockY * chessboardSize[0] + blockX) // 2127 elif (mode == "ARUCO"):128 markerID = firstMarkerID129 elif (mode == "ARUCOGRID"):130 markerID = firstMarkerID + (blockY * chessboardSize[0] + blockX)131 marker = MarkerPrinter.ArucoBits(dictionary, markerID)132 markerSize = marker.shape[0]133 unitLength = markerLength / (float)(markerSize + borderBits * 2)134 markerBitMap = np.zeros(shape = (markerSize+borderBits*2, markerSize+borderBits*2), dtype = bool)135 markerBitMap[borderBits:-borderBits,borderBits:-borderBits] = marker136 markerBitMap = np.swapaxes(markerBitMap, 0, 1)137 # Compute edges138 hEdges = np.zeros(shape = (markerSize+1,markerSize+1), dtype = bool)139 vEdges = np.zeros(shape = (markerSize+1,markerSize+1), dtype = bool)140 for mx in range(markerSize):141 for my in range(markerSize+1):142 if ( markerBitMap[mx + borderBits, my + borderBits - 1] ^ markerBitMap[mx + borderBits, my + borderBits]):143 hEdges[mx, my] = True144 for mx in range(markerSize+1):145 for my in range(markerSize):146 if ( markerBitMap[mx + borderBits - 1, my + borderBits] ^ markerBitMap[mx + borderBits, my + borderBits]):147 vEdges[mx, my] = True148 # Use for debug, check edge or position is correct or not149 if(MarkerPrinter.debugMode is not None):150 if(MarkerPrinter.debugMode.upper() == "LINE"):151 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)152 context.set_line_width(unitLength * 0.1)153 for mx in range(markerSize+1):154 for my in range(markerSize+1):155 if(hEdges[mx, my]):156 context.move_to(originX + unitLength * (mx + borderBits ), originY + unitLength * (my + borderBits ))157 context.line_to(originX + unitLength * (mx + borderBits + 1), originY + unitLength * (my + borderBits ))158 context.stroke()159 if(vEdges[mx, my]):160 context.move_to(originX + unitLength * (mx + borderBits ), originY + unitLength * (my + borderBits ))161 context.line_to(originX + unitLength * (mx + borderBits ), originY + unitLength * (my + borderBits + 1))162 context.stroke()163 elif(MarkerPrinter.debugMode.upper() == "BLOCK"):164 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)165 for mx in range(markerSize):166 for my in range(markerSize):167 if(markerBitMap[mx + borderBits, my + borderBits]):168 context.rectangle(169 originX + unitLength * (mx + borderBits),170 originY + unitLength * (my + borderBits),171 unitLength, unitLength)172 context.fill()173 else:174 while(True):175 found = False176 # Find start position177 sx = 0178 sy = 0179 for my in range(markerSize):180 for mx in range(markerSize):181 if(hEdges[mx, my]):182 found = True183 sx = mx184 sy = my185 if(markerBitMap[sx + borderBits, sy + borderBits - 1]):186 context.set_source_rgba(0.0, 0.0, 0.0, 1.0)187 else:188 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)189 break190 if(found):191 break192 context.move_to (originX + unitLength * (sx + borderBits), originY + unitLength * (sy + borderBits))193 # Use wall follower maze solving algorithm to draw white part194 cx = sx195 cy = sy196 cd = 3 # 0 right, 1 down, 2 left, 3 up197 while(True):198 nd = (cd + 1)%4199 moved = False200 if(nd == 0):201 if(hEdges[cx, cy]):202 hEdges[cx, cy] = False203 cx = cx + 1204 moved = True205 elif(nd == 1):206 if(vEdges[cx, cy]):207 vEdges[cx, cy] = False208 cy = cy + 1209 moved = True210 elif(nd == 2):211 if(hEdges[cx - 1, cy]):212 hEdges[cx - 1, cy] = False213 cx = cx - 1214 moved = True215 elif(nd == 3):216 if(vEdges[cx, cy - 1]):217 vEdges[cx, cy - 1] = False218 cy = cy - 1219 moved = True220 if((cx == sx) and (cy == sy)):221 context.close_path ()222 break223 else:224 if(moved):225 context.line_to(originX + unitLength * (cx + borderBits), originY + unitLength * (cy + borderBits))226 cd = nd227 if (found):228 context.fill()229 else:230 break231 else:232 originX = (blockX - originX) * squareLength + pageBorderX233 originY = (blockY - originY) * squareLength + pageBorderY234 context.set_source_rgba(0.0, 0.0, 0.0, 1.0)235 context.rectangle(originX, originY, squareLength, squareLength)236 context.fill()237 def __CheckChessMarkerImage(chessboardSize, squareLength, subSize=None, pageBorder=(0,0)):238 if(len(chessboardSize) != 2):239 raise ValueError("len(chessboardSize) != 2")240 else:241 sizeX, sizeY = chessboardSize242 if(len(pageBorder) != 2):243 raise ValueError("len(pageBorder) != 2")244 else:245 pageBorderX, pageBorderY = pageBorder246 if(sizeX <= 1):247 raise ValueError("sizeX <= 1")248 if(sizeY <= 1):249 raise ValueError("sizeY <= 1")250 if(squareLength <= 0):251 raise ValueError("squareLength <= 0")252 if(pageBorderX < 0):253 raise ValueError("pageBorderX < 0")254 if(pageBorderY < 0):255 raise ValueError("pageBorderY < 0")256 if(subSize is not None):257 subSizeX, subSizeY = subSize258 if(subSizeX < 0):259 raise ValueError("subSizeX < 0")260 if(subSizeY < 0):261 raise ValueError("subSizeY < 0")262 def PreviewChessMarkerImage(chessboardSize, squareLength, pageBorder=(0, 0), dpi=96):263 MarkerPrinter.__CheckChessMarkerImage(chessboardSize, squareLength, pageBorder=pageBorder)264 squareLength = squareLength * MarkerPrinter.ptPerMeter265 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)266 prevImage = None267 with tempfile.TemporaryDirectory() as tmpdirname:268 with MarkerPrinter.surface[".SVG"] (269 os.path.join(tmpdirname, "tempSVG.svg"),270 chessboardSize[0] * squareLength + pageBorder[0] * 2,271 chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:272 context = cairo.Context(surface)273 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)274 context.rectangle(0, 0,275 chessboardSize[0] * squareLength + pageBorder[0] * 2,276 chessboardSize[1] * squareLength + pageBorder[1] * 2)277 context.fill()278 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)279 context.rectangle(pageBorder[0], pageBorder[1],280 chessboardSize[0] * squareLength,281 chessboardSize[1] * squareLength)282 context.fill()283 for bx in range(chessboardSize[0]):284 for by in range(chessboardSize[1]):285 MarkerPrinter.__DrawBlock(286 context = context,287 chessboardSize = chessboardSize,288 squareLength = squareLength,289 blockX = bx,290 blockY = by,291 pageBorderX = pageBorder[0],292 pageBorderY = pageBorder[1],293 mode = "CHESS")294 with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:295 prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))296 return prevImage297 def GenChessMarkerImage(filePath, chessboardSize, squareLength, subSize=None, pageBorder=(0, 0)):298 MarkerPrinter.__CheckChessMarkerImage(chessboardSize, squareLength, subSize=subSize, pageBorder=pageBorder)299 squareLength = squareLength * MarkerPrinter.ptPerMeter300 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)301 # Check302 path, nameExt = os.path.split(filePath)303 name, ext = os.path.splitext(nameExt)304 if(len(path) > 0):305 if not(os.path.isdir(path)):306 os.makedirs(path)307 if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):308 raise ValueError("file extention is not supported, should be: svg, ps, pdf")309 # Draw310 with MarkerPrinter.surface[ext.upper()] (311 filePath,312 chessboardSize[0] * squareLength + pageBorder[0] * 2,313 chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:314 context = cairo.Context(surface)315 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)316 context.rectangle(0, 0,317 chessboardSize[0] * squareLength + pageBorder[0] * 2,318 chessboardSize[1] * squareLength + pageBorder[1] * 2)319 context.fill()320 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)321 context.rectangle(pageBorder[0], pageBorder[1],322 chessboardSize[0] * squareLength,323 chessboardSize[1] * squareLength)324 context.fill()325 for bx in range(chessboardSize[0]):326 for by in range(chessboardSize[1]):327 MarkerPrinter.__DrawBlock(328 context = context,329 chessboardSize = chessboardSize,330 squareLength = squareLength,331 blockX = bx,332 blockY = by,333 pageBorderX = pageBorder[0],334 pageBorderY = pageBorder[1],335 mode = "CHESS" )336 if(subSize is not None):337 subDivide = (\338 chessboardSize[0] // subSize[0] + int(chessboardSize[0] % subSize[0] > 0),339 chessboardSize[1] // subSize[1] + int(chessboardSize[1] % subSize[1] > 0))340 subChessboardBlockX = np.clip ( np.arange(0, subSize[0] * subDivide[0] + 1, subSize[0]), 0, chessboardSize[0])341 subChessboardBlockY = np.clip ( np.arange(0, subSize[1] * subDivide[1] + 1, subSize[1]), 0, chessboardSize[1])342 subChessboardSliceX = subChessboardBlockX.astype(np.float) * squareLength343 subChessboardSliceY = subChessboardBlockY.astype(np.float) * squareLength344 for subXID in range(subDivide[0]):345 for subYID in range(subDivide[1]):346 subName = name + \347 "_X" + str(subChessboardBlockX[subXID]) + "_" + str(subChessboardBlockX[subXID+1]) + \348 "_Y" + str(subChessboardBlockY[subYID]) + "_" + str(subChessboardBlockY[subYID+1])349 with MarkerPrinter.surface[ext.upper()](350 os.path.join(path, subName + ext),351 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,352 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2) as surface:353 context = cairo.Context(surface)354 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)355 context.rectangle(0, 0,356 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,357 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2)358 context.fill()359 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)360 context.rectangle(pageBorder[0], pageBorder[1],361 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID],362 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID])363 context.fill()364 for bx in range(subChessboardBlockX[subXID+1] - subChessboardBlockX[subXID]):365 for by in range(subChessboardBlockY[subYID+1] - subChessboardBlockY[subYID]):366 MarkerPrinter.__DrawBlock(367 context = context,368 chessboardSize = chessboardSize,369 squareLength = squareLength,370 blockX = subChessboardBlockX[subXID] + bx,371 blockY = subChessboardBlockY[subYID] + by,372 originX = subChessboardBlockX[subXID],373 originY = subChessboardBlockY[subYID],374 pageBorderX = pageBorder[0],375 pageBorderY = pageBorder[1],376 mode = "CHESS" )377 def __CheckArucoMarkerImage(dictionary, markerID, markerLength, borderBits=1, pageBorder=(0, 0)):378 if(len(pageBorder) != 2):379 raise ValueError("len(pageBorder) != 2")380 else:381 pageBorderX, pageBorderY = pageBorder382 if not (dictionary in MarkerPrinter.arucoDictBytesList):383 raise ValueError("dictionary is not support")384 if(MarkerPrinter.arucoDictBytesList[dictionary].shape[0] <= markerID ):385 raise ValueError("markerID is not in aruce dictionary")386 if(markerID < 0):387 raise ValueError("markerID < 0")388 if(markerLength <= 0):389 raise ValueError("markerLength <= 0")390 if(borderBits <= 0):391 raise ValueError("borderBits <= 0")392 if(pageBorderX < 0):393 raise ValueError("pageBorderX < 0")394 if(pageBorderY < 0):395 raise ValueError("pageBorderY < 0")396 def PreviewArucoMarkerImage(dictionary, markerID, markerLength, borderBits=1, pageBorder=(0, 0), dpi=96):397 MarkerPrinter.__CheckArucoMarkerImage(dictionary, markerID, markerLength, borderBits=borderBits, pageBorder=pageBorder)398 markerLength = markerLength * MarkerPrinter.ptPerMeter399 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)400 prevImage = None401 with tempfile.TemporaryDirectory() as tmpdirname:402 with MarkerPrinter.surface[".SVG"] (403 os.path.join(tmpdirname, "tempSVG.svg"),404 markerLength + pageBorder[0] * 2,405 markerLength + pageBorder[1] * 2) as surface:406 context = cairo.Context(surface)407 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)408 context.rectangle(0, 0,409 markerLength + pageBorder[0] * 2,410 markerLength + pageBorder[1] * 2)411 context.fill()412 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)413 context.rectangle(pageBorder[0], pageBorder[1],414 markerLength,415 markerLength)416 context.fill()417 MarkerPrinter.__DrawBlock(418 context = context,419 dictionary = dictionary,420 markerLength = markerLength,421 borderBits = borderBits,422 firstMarkerID = markerID,423 pageBorderX = pageBorder[0],424 pageBorderY = pageBorder[1],425 mode = "ARUCO")426 with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:427 prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))428 return prevImage429 def GenArucoMarkerImage(filePath, dictionary, markerID, markerLength, borderBits=1, pageBorder=(0, 0)):430 MarkerPrinter.__CheckArucoMarkerImage(dictionary, markerID, markerLength, borderBits=borderBits, pageBorder=pageBorder)431 markerLength = markerLength * MarkerPrinter.ptPerMeter432 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)433 # Check434 path, nameExt = os.path.split(filePath)435 name, ext = os.path.splitext(nameExt)436 if(len(path) > 0):437 if not(os.path.isdir(path)):438 os.makedirs(path)439 if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):440 raise ValueError("file extention is not supported, should be: svg, ps, pdf")441 # Draw442 with MarkerPrinter.surface[ext.upper()] (443 filePath,444 markerLength + pageBorder[0] * 2,445 markerLength + pageBorder[1] * 2) as surface:446 context = cairo.Context(surface)447 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)448 context.rectangle(0, 0,449 markerLength + pageBorder[0] * 2,450 markerLength + pageBorder[1] * 2)451 context.fill()452 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)453 context.rectangle(pageBorder[0], pageBorder[1],454 markerLength,455 markerLength)456 context.fill()457 MarkerPrinter.__DrawBlock(458 context = context,459 dictionary = dictionary,460 markerLength = markerLength,461 borderBits = borderBits,462 firstMarkerID = markerID,463 pageBorderX = pageBorder[0],464 pageBorderY = pageBorder[1],465 mode = "ARUCO")466 def __CheckCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=1, subSize=None, pageBorder=(0, 0)):467 if(len(chessboardSize) != 2):468 raise ValueError("len(chessboardSize) != 2")469 else:470 sizeX, sizeY = chessboardSize471 if(len(pageBorder) != 2):472 raise ValueError("len(pageBorder) != 2")473 else:474 pageBorderX, pageBorderY = pageBorder475 if not (dictionary in MarkerPrinter.arucoDictBytesList):476 raise ValueError("dictionary is not support")477 if(MarkerPrinter.arucoDictBytesList[dictionary].shape[0] < (( sizeX * sizeY ) // 2)):478 raise ValueError("aruce dictionary is not enough for your board size")479 if(sizeX <= 1):480 raise ValueError("sizeX <= 1")481 if(sizeY <= 1):482 raise ValueError("sizeY <= 1")483 if(squareLength <= 0):484 raise ValueError("squareLength <= 0")485 if(markerLength <= 0):486 raise ValueError("markerLength <= 0")487 if(squareLength < markerLength):488 raise ValueError("squareLength < markerLength")489 if(borderBits <= 0):490 raise ValueError("borderBits <= 0")491 if(pageBorderX < 0):492 raise ValueError("pageBorderX < 0")493 if(pageBorderY < 0):494 raise ValueError("pageBorderY < 0")495 if(subSize is not None):496 subSizeX, subSizeY = subSize497 if(subSizeX < 0):498 raise ValueError("subSizeX < 0")499 if(subSizeY < 0):500 raise ValueError("subSizeY < 0")501 def PreviewCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=1, pageBorder=(0, 0), dpi=96):502 MarkerPrinter.__CheckCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=borderBits, pageBorder=pageBorder)503 squareLength = squareLength * MarkerPrinter.ptPerMeter504 markerLength = markerLength * MarkerPrinter.ptPerMeter505 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)506 prevImage = None507 with tempfile.TemporaryDirectory() as tmpdirname:508 with MarkerPrinter.surface[".SVG"] (509 os.path.join(tmpdirname, "tempSVG.svg"),510 chessboardSize[0] * squareLength + pageBorder[0] * 2,511 chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:512 context = cairo.Context(surface)513 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)514 context.rectangle(0, 0,515 chessboardSize[0] * squareLength + pageBorder[0] * 2,516 chessboardSize[1] * squareLength + pageBorder[1] * 2)517 context.fill()518 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)519 context.rectangle(pageBorder[0], pageBorder[1],520 chessboardSize[0] * squareLength,521 chessboardSize[1] * squareLength)522 context.fill()523 for bx in range(chessboardSize[0]):524 for by in range(chessboardSize[1]):525 MarkerPrinter.__DrawBlock(526 context = context,527 dictionary = dictionary,528 markerLength = markerLength,529 borderBits = borderBits,530 chessboardSize = chessboardSize,531 squareLength = squareLength,532 blockX = bx,533 blockY = by,534 pageBorderX = pageBorder[0],535 pageBorderY = pageBorder[1],536 mode = "CHARUCO")537 with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:538 prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))539 return prevImage540 def GenCharucoMarkerImage(filePath, dictionary, chessboardSize, squareLength, markerLength, borderBits=1, subSize=None, pageBorder=(0, 0)):541 MarkerPrinter.__CheckCharucoMarkerImage(dictionary, chessboardSize, squareLength, markerLength, borderBits=borderBits, subSize=subSize, pageBorder=pageBorder)542 squareLength = squareLength * MarkerPrinter.ptPerMeter543 markerLength = markerLength * MarkerPrinter.ptPerMeter544 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)545 # Check546 path, nameExt = os.path.split(filePath)547 name, ext = os.path.splitext(nameExt)548 if(len(path) > 0):549 if not(os.path.isdir(path)):550 os.makedirs(path)551 if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):552 raise ValueError("file extention is not supported, should be: svg, ps, pdf")553 # Draw554 with MarkerPrinter.surface[ext.upper()] (555 filePath,556 chessboardSize[0] * squareLength + pageBorder[0] * 2,557 chessboardSize[1] * squareLength + pageBorder[1] * 2) as surface:558 context = cairo.Context(surface)559 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)560 context.rectangle(0, 0,561 chessboardSize[0] * squareLength + pageBorder[0] * 2,562 chessboardSize[1] * squareLength + pageBorder[1] * 2)563 context.fill()564 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)565 context.rectangle(pageBorder[0], pageBorder[1],566 chessboardSize[0] * squareLength,567 chessboardSize[1] * squareLength)568 context.fill()569 for bx in range(chessboardSize[0]):570 for by in range(chessboardSize[1]):571 MarkerPrinter.__DrawBlock(572 context = context,573 dictionary = dictionary,574 markerLength = markerLength,575 borderBits = borderBits,576 chessboardSize = chessboardSize,577 squareLength = squareLength,578 blockX = bx,579 blockY = by,580 pageBorderX = pageBorder[0],581 pageBorderY = pageBorder[1],582 mode = "CHARUCO")583 if(subSize is not None):584 subDivide = (\585 chessboardSize[0] // subSize[0] + int(chessboardSize[0] % subSize[0] > 0),586 chessboardSize[1] // subSize[1] + int(chessboardSize[1] % subSize[1] > 0))587 subChessboardBlockX = np.clip ( np.arange(0, subSize[0] * subDivide[0] + 1, subSize[0]), 0, chessboardSize[0])588 subChessboardBlockY = np.clip ( np.arange(0, subSize[1] * subDivide[1] + 1, subSize[1]), 0, chessboardSize[1])589 subChessboardSliceX = subChessboardBlockX.astype(np.float) * squareLength590 subChessboardSliceY = subChessboardBlockY.astype(np.float) * squareLength591 for subXID in range(subDivide[0]):592 for subYID in range(subDivide[1]):593 subName = name + \594 "_X" + str(subChessboardBlockX[subXID]) + "_" + str(subChessboardBlockX[subXID+1]) + \595 "_Y" + str(subChessboardBlockY[subYID]) + "_" + str(subChessboardBlockY[subYID+1])596 with MarkerPrinter.surface[ext.upper()](597 os.path.join(path, subName + ext),598 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,599 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2) as surface:600 context = cairo.Context(surface)601 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)602 context.rectangle(0, 0,603 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,604 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2)605 context.fill()606 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)607 context.rectangle(pageBorder[0], pageBorder[1],608 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID],609 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID])610 context.fill()611 for bx in range(subChessboardBlockX[subXID+1] - subChessboardBlockX[subXID]):612 for by in range(subChessboardBlockY[subYID+1] - subChessboardBlockY[subYID]):613 MarkerPrinter.__DrawBlock(614 context = context,615 dictionary = dictionary,616 markerLength = markerLength,617 borderBits = borderBits,618 chessboardSize = chessboardSize,619 squareLength = squareLength,620 blockX = subChessboardBlockX[subXID] + bx,621 blockY = subChessboardBlockY[subYID] + by,622 originX = subChessboardBlockX[subXID],623 originY = subChessboardBlockY[subYID],624 pageBorderX = pageBorder[0],625 pageBorderY = pageBorder[1],626 mode = "CHARUCO")627 def __CheckArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=1, subSize=None, pageBorder=(0, 0)):628 if(len(chessboardSize) != 2):629 raise ValueError("len(chessboardSize) != 2")630 else:631 sizeX, sizeY = chessboardSize632 if(len(pageBorder) != 2):633 raise ValueError("len(pageBorder) != 2")634 else:635 pageBorderX, pageBorderY = pageBorder636 if not (dictionary in MarkerPrinter.arucoDictBytesList):637 raise ValueError("dictionary is not support")638 if(MarkerPrinter.arucoDictBytesList[dictionary].shape[0] < (( sizeX * sizeY ) + firstMarker)):639 raise ValueError("aruce dictionary is not enough for your board size and firstMarker")640 if(sizeX <= 1):641 raise ValueError("sizeX <= 1")642 if(sizeY <= 1):643 raise ValueError("sizeY <= 1")644 if(markerLength <= 0):645 raise ValueError("markerLength <= 0")646 if(markerSeparation <= 0):647 raise ValueError("markerSeparation <= 0")648 if(borderBits <= 0):649 raise ValueError("borderBits <= 0")650 if(pageBorderX < 0):651 raise ValueError("pageBorderX < 0")652 if(pageBorderY < 0):653 raise ValueError("pageBorderY < 0")654 if(subSize is not None):655 subSizeX, subSizeY = subSize656 if(subSizeX < 0):657 raise ValueError("subSizeX < 0")658 if(subSizeY < 0):659 raise ValueError("subSizeY < 0")660 def PreviewArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=1, pageBorder=(0, 0), dpi=96):661 MarkerPrinter.__CheckArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=borderBits, pageBorder=pageBorder)662 markerLength = markerLength * MarkerPrinter.ptPerMeter663 markerSeparation = markerSeparation * MarkerPrinter.ptPerMeter664 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)665 prevImage = None666 with tempfile.TemporaryDirectory() as tmpdirname:667 with MarkerPrinter.surface[".SVG"] (668 os.path.join(tmpdirname, "tempSVG.svg"),669 chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,670 chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2) as surface:671 context = cairo.Context(surface)672 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)673 context.rectangle(0, 0,674 chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,675 chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2)676 context.fill()677 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)678 context.rectangle(pageBorder[0], pageBorder[1],679 chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation,680 chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation)681 context.fill()682 for bx in range(chessboardSize[0]):683 for by in range(chessboardSize[1]):684 MarkerPrinter.__DrawBlock(685 context = context,686 dictionary = dictionary,687 markerLength = markerLength,688 borderBits = borderBits,689 chessboardSize = chessboardSize,690 squareLength = markerLength + markerSeparation,691 firstMarkerID = firstMarker,692 blockX = bx,693 blockY = by,694 pageBorderX = pageBorder[0],695 pageBorderY = pageBorder[1],696 mode = "ARUCOGRID")697 with open(os.path.join(tmpdirname, "tempSVG.svg")) as file:698 prevImage = Image.open(io.BytesIO(svg2png(bytestring=file.read(), dpi=dpi)))699 return prevImage700 def GenArucoGridMarkerImage(filePath, dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=1, subSize=None, pageBorder=(0, 0)):701 MarkerPrinter.__CheckArucoGridMarkerImage(dictionary, chessboardSize, markerLength, markerSeparation, firstMarker, borderBits=borderBits, subSize=subSize, pageBorder=pageBorder)702 markerLength = markerLength * MarkerPrinter.ptPerMeter703 markerSeparation = markerSeparation * MarkerPrinter.ptPerMeter704 pageBorder = (pageBorder[0] * MarkerPrinter.ptPerMeter, pageBorder[1] * MarkerPrinter.ptPerMeter)705 # Check706 path, nameExt = os.path.split(filePath)707 name, ext = os.path.splitext(nameExt)708 if(len(path) > 0):709 if not(os.path.isdir(path)):710 os.makedirs(path)711 if((ext.upper() != ".SVG") and (ext.upper() != ".PS") and (ext.upper() != ".PDF")):712 raise ValueError("file extention is not supported, should be: svg, ps, pdf")713 # Draw714 with MarkerPrinter.surface[ext.upper()] (715 filePath,716 chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,717 chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2) as surface:718 context = cairo.Context(surface)719 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)720 context.rectangle(0, 0,721 chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation + pageBorder[0] * 2,722 chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation + pageBorder[1] * 2)723 context.fill()724 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)725 context.rectangle(pageBorder[0], pageBorder[1],726 chessboardSize[0] * markerLength + (chessboardSize[0] - 1) * markerSeparation,727 chessboardSize[1] * markerLength + (chessboardSize[1] - 1) * markerSeparation)728 context.fill()729 for bx in range(chessboardSize[0]):730 for by in range(chessboardSize[1]):731 MarkerPrinter.__DrawBlock(732 context = context,733 dictionary = dictionary,734 markerLength = markerLength,735 borderBits = borderBits,736 chessboardSize = chessboardSize,737 squareLength = markerLength + markerSeparation,738 firstMarkerID = firstMarker,739 blockX = bx,740 blockY = by,741 pageBorderX = pageBorder[0],742 pageBorderY = pageBorder[1],743 mode = "ARUCOGRID")744 if(subSize is not None):745 subDivide = (\746 chessboardSize[0] // subSize[0] + int(chessboardSize[0] % subSize[0] > 0),747 chessboardSize[1] // subSize[1] + int(chessboardSize[1] % subSize[1] > 0))748 subChessboardBlockX = np.clip ( np.arange(0, subSize[0] * subDivide[0] + 1, subSize[0]), 0, chessboardSize[0])749 subChessboardBlockY = np.clip ( np.arange(0, subSize[1] * subDivide[1] + 1, subSize[1]), 0, chessboardSize[1])750 subChessboardSliceX = subChessboardBlockX.astype(np.float) * (markerLength + markerSeparation)751 subChessboardSliceY = subChessboardBlockY.astype(np.float) * (markerLength + markerSeparation)752 subChessboardSliceX[-1] -= markerSeparation753 subChessboardSliceY[-1] -= markerSeparation754 for subXID in range(subDivide[0]):755 for subYID in range(subDivide[1]):756 subName = name + \757 "_X" + str(subChessboardBlockX[subXID]) + "_" + str(subChessboardBlockX[subXID+1]) + \758 "_Y" + str(subChessboardBlockY[subYID]) + "_" + str(subChessboardBlockY[subYID+1])759 with MarkerPrinter.surface[ext.upper()](760 os.path.join(path, subName + ext),761 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,762 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2) as surface:763 context = cairo.Context(surface)764 context.set_source_rgba(0.5, 0.5, 0.5, 1.0)765 context.rectangle(0, 0,766 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID] + pageBorder[0] * 2,767 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID] + pageBorder[1] * 2)768 context.fill()769 context.set_source_rgba(1.0, 1.0, 1.0, 1.0)770 context.rectangle(pageBorder[0], pageBorder[1],771 subChessboardSliceX[subXID+1] - subChessboardSliceX[subXID],772 subChessboardSliceY[subYID+1] - subChessboardSliceY[subYID])773 context.fill()774 for bx in range(subChessboardBlockX[subXID+1] - subChessboardBlockX[subXID]):775 for by in range(subChessboardBlockY[subYID+1] - subChessboardBlockY[subYID]):776 MarkerPrinter.__DrawBlock(777 context = context,778 dictionary = dictionary,779 markerLength = markerLength,780 borderBits = borderBits,781 chessboardSize = chessboardSize,782 squareLength = markerLength + markerSeparation,783 firstMarkerID = firstMarker,784 blockX = subChessboardBlockX[subXID] + bx,785 blockY = subChessboardBlockY[subYID] + by,786 originX = subChessboardBlockX[subXID],787 originY = subChessboardBlockY[subYID],788 pageBorderX = pageBorder[0],789 pageBorderY = pageBorder[1],790 mode = "ARUCOGRID")791if __name__ == '__main__':792 parser = ArgumentParser()793 # Save marker image parameters794 chessGroup = parser.add_argument_group('chess', 'Chessboard')795 arucoGroup = parser.add_argument_group('aruco', 'ArUco')796 arucoGridGroup = parser.add_argument_group('aruco_grid', 'ArUco grid')797 charucoGroup = parser.add_argument_group('charuco', 'ChArUco')798 exclusiveGroup = parser.add_mutually_exclusive_group()799 exclusiveGroup.add_argument(800 "--chess", action='store_true', default=False,801 help="Choose to save chessboard marker")802 exclusiveGroup.add_argument(803 "--aruco", action='store_true', default=False,804 help="Choose to save ArUco marker")805 exclusiveGroup.add_argument(806 "--aruco_grid", action='store_true', default=False,807 help="Choose to save ArUco grid marker")808 exclusiveGroup.add_argument(809 "--charuco", action='store_true', default=False,810 help="Choose to save ChArUco marker")811 # Utility functions parameters812 exclusiveGroup.add_argument(813 "--generate", dest="arucoDataFileName",814 help="Generate aruco data to FILE", metavar="FILE")815 exclusiveGroup.add_argument(816 "--list_dictionary", action='store_true', default=False,817 help="List predefined aruco dictionary")818 # Parameters819 # fileName820 parser.add_argument(821 "--file", dest="fileName", default="./image.pdf",822 help="Save marker image to FILE", metavar="FILE")823 for group in [chessGroup, arucoGroup, arucoGridGroup, charucoGroup]:824 group.add_argument(825 "--" + group.title + "_file", dest="fileName",826 help="Save marker image to FILE", metavar="FILE")827 # dictionary828 parser.add_argument(829 "--dictionary", dest="dictionary", default="DICT_ARUCO_ORIGINAL",830 help="Generate marker via predefined DICTIONARY aruco dictionary", metavar="DICTIONARY")831 for group in [arucoGroup, arucoGridGroup, charucoGroup]:832 group.add_argument(833 "--" + group.title + "_dictionary", dest="dictionary",834 help="Generate marker via predefined DICTIONARY aruco dictionary", metavar="DICTIONARY")835 # size836 parser.add_argument(837 "--size_x", dest="sizeX", default="16",838 help="Save marker image with N board width", metavar="N")839 parser.add_argument(840 "--size_y", dest="sizeY", default="9",841 help="Save marker image with N board height", metavar="N")842 for group in [chessGroup, arucoGridGroup, charucoGroup]:843 group.add_argument(844 "--" + group.title + "_size_x", dest="sizeX",845 help="Save marker image with N board width", metavar="N")846 group.add_argument(847 "--" + group.title + "_size_y", dest="sizeY",848 help="Save marker image with N board height", metavar="N")849 # length850 parser.add_argument(851 "--square_length", dest="squareLength", default="0.09",852 help="Save marker image with L square length (Unit: meter)", metavar="L")853 parser.add_argument(854 "--marker_length", dest="markerLength", default="0.07",855 help="Save marker image with L marker length (Unit: meter)", metavar="L")856 parser.add_argument(857 "--marker_separation", dest="markerSeparation", default="0.02",858 help="Save marker image with L separation length (Unit: meter)", metavar="L")859 for group in [chessGroup, charucoGroup]:860 group.add_argument(861 "--" + group.title + "_square_length", dest="squareLength",862 help="Save marker image with L blocks length (Unit: meter)", metavar="L")863 for group in [arucoGroup, arucoGridGroup, charucoGroup]:864 group.add_argument(865 "--" + group.title + "_marker_length", dest="markerLength",866 help="Save marker image with L marker length (Unit: meter)", metavar="L")867 for group in [arucoGridGroup]:868 group.add_argument(869 "--" + group.title + "_marker_separation", dest="markerSeparation",870 help="Save marker image with L gap length (Unit: meter)", metavar="L")871 # else872 parser.add_argument(873 "--marker_id", dest="markerID", default="0",874 help="Save marker image with ID marker", metavar="ID")875 parser.add_argument(876 "--first_marker", dest="firstMarker", default="0",877 help="Save marker image that start with ID marker", metavar="ID")878 parser.add_argument(879 "--border_bits", dest="borderBits", default="1",880 help="Save marker image with N border size", metavar="N")881 for group in [arucoGroup]:882 group.add_argument(883 "--" + group.title + "_marker_id", dest="markerID",884 help="Save marker image with ID marker", metavar="ID")885 for group in [arucoGridGroup]:886 group.add_argument(887 "--" + group.title + "_first_marker", dest="firstMarker",888 help="Save marker image that start with ID marker", metavar="ID")889 for group in [arucoGroup, arucoGridGroup, charucoGroup]:890 group.add_argument(891 "--" + group.title + "_border_bits", dest="borderBits",892 help="Save marker image with N border size", metavar="N")893 # sub size894 parser.add_argument(895 "--sub_size_x", dest="subSizeX", default="0",896 help="Save marker image with N chuck width", metavar="N")897 parser.add_argument(898 "--sub_size_y", dest="subSizeY", default="0",899 help="Save marker image with N chuck height", metavar="N")900 for group in [chessGroup, arucoGridGroup, charucoGroup]:901 group.add_argument(902 "--" + group.title + "_sub_size_x", dest="subSizeX",903 help="Save marker image with N chuck width", metavar="N")904 group.add_argument(905 "--" + group.title + "_sub_size_y", dest="subSizeY",906 help="Save marker image with N chuck height", metavar="N")907 # page border908 parser.add_argument(909 "--page_border_x", dest="pageBorderX", default="0",910 help="Save with page border width L length (Unit: meter)", metavar="L")911 parser.add_argument(912 "--page_border_y", dest="pageBorderY", default="0",913 help="Save with page border height L length (Unit: meter)", metavar="L")914 for group in [chessGroup, arucoGroup, arucoGridGroup, charucoGroup]:915 group.add_argument(916 "--" + group.title + "_page_border_x", dest="pageBorderX", default="0",917 help="Save with page border width L length (Unit: meter)", metavar="L")918 group.add_argument(919 "--" + group.title + "_page_border_y", dest="pageBorderY", default="0",920 help="Save with page border height L length (Unit: meter)", metavar="L")921 # Run922 args = parser.parse_args()923 if(args.arucoDataFileName is not None):924 print("Generate aruco data to: " + args.arucoDataFileName)925 SaveArucoDictBytesList(args.arucoDataFileName)926 elif(args.list_dictionary):927 print("List predefined aruco dictionary")928 for i in MarkerPrinter.arucoDictBytesList.keys():929 print(i)930 elif(args.chess):931 try:932 sizeX = int(args.sizeX)933 sizeY = int(args.sizeY)934 squareLength = float(args.squareLength)935 subSizeX = int(args.subSizeX)936 subSizeY = int(args.subSizeY)937 pageBorderX = float(args.pageBorderX)938 pageBorderY = float(args.pageBorderY)939 except ValueError as e:940 warnings.warn(str(e))941 else:942 print("Save chessboard marker with parms: " + \943 str({ \944 "fileName": args.fileName, \945 "sizeX": sizeX, \946 "sizeY": sizeY, \947 "squareLength": squareLength, \948 "subSizeX": subSizeX, \949 "subSizeY": subSizeY, \950 "pageBorderX": pageBorderX, \951 "pageBorderY": pageBorderY, \952 }))953 subSize = None954 if(subSizeX > 0):955 if(subSizeY > 0):956 subSize = (subSizeX, subSizeY)957 else:958 subSize = (subSizeX, sizeY)959 else:960 if(subSizeY > 0):961 subSize = (sizeX, subSizeY)962 else:963 subSize = None964 # Gen965 MarkerPrinter.GenChessMarkerImage(args.fileName, (sizeX, sizeY), squareLength, subSize = subSize, pageBorder = (pageBorderX, pageBorderY))966 elif(args.aruco):967 try:968 markerLength = float(args.markerLength)969 markerID = int(args.markerID)970 borderBits = int(args.borderBits)971 pageBorderX = float(args.pageBorderX)972 pageBorderY = float(args.pageBorderY)973 except ValueError as e:974 warnings.warn(str(e))975 else:976 print("Save ArUco marker with parms: " + \977 str({ \978 "fileName": args.fileName, \979 "dictionary": args.dictionary, \980 "markerLength": markerLength, \981 "markerID": markerID, \982 "borderBits": borderBits, \983 "pageBorderX": pageBorderX, \984 "pageBorderY": pageBorderY, \985 }))986 # Gen987 MarkerPrinter.GenArucoMarkerImage(args.fileName, args.dictionary, markerID, markerLength, borderBits=borderBits, pageBorder = (pageBorderX, pageBorderY))988 elif(args.aruco_grid):989 try:990 sizeX = int(args.sizeX)991 sizeY = int(args.sizeY)992 markerLength = float(args.markerLength)993 markerSeparation = float(args.markerSeparation)994 firstMarker = int(args.firstMarker)995 borderBits = int(args.borderBits)996 subSizeX = int(args.subSizeX)997 subSizeY = int(args.subSizeY)998 pageBorderX = float(args.pageBorderX)999 pageBorderY = float(args.pageBorderY)1000 except ValueError as e:1001 warnings.warn(str(e))1002 else:1003 print("Save ArUco grid marker with parms: " + \1004 str({ \1005 "fileName": args.fileName, \1006 "dictionary": args.dictionary, \1007 "sizeX": sizeX, \1008 "sizeY": sizeY, \1009 "markerLength": markerLength, \1010 "markerSeparation": markerSeparation, \1011 "firstMarker": firstMarker, \1012 "borderBits": borderBits, \1013 "subSizeX": subSizeX, \1014 "subSizeY": subSizeY, \1015 "pageBorderX": pageBorderX, \1016 "pageBorderY": pageBorderY, \1017 }))1018 subSize = None1019 if(subSizeX > 0):1020 if(subSizeY > 0):1021 subSize = (subSizeX, subSizeY)1022 else:1023 subSize = (subSizeX, sizeY)1024 else:1025 if(subSizeY > 0):1026 subSize = (sizeX, subSizeY)1027 else:1028 subSize = None1029 # Gen1030 MarkerPrinter.GenArucoGridMarkerImage(args.fileName, args.dictionary, (sizeX, sizeY), markerLength, markerSeparation, firstMarker, borderBits=borderBits, subSize=subSize, pageBorder = (pageBorderX, pageBorderY))1031 elif(args.charuco):1032 try:1033 sizeX = int(args.sizeX)1034 sizeY = int(args.sizeY)1035 squareLength = float(args.squareLength)1036 markerLength = float(args.markerLength)1037 borderBits = int(args.borderBits)1038 subSizeX = int(args.subSizeX)1039 subSizeY = int(args.subSizeY)1040 pageBorderX = float(args.pageBorderX)1041 pageBorderY = float(args.pageBorderY)1042 except ValueError as e:1043 warnings.warn(str(e))1044 else:1045 print("Save ChArUco marker with parms: " + \1046 str({ \1047 "fileName": args.fileName, \1048 "dictionary": args.dictionary, \1049 "sizeX": sizeX, \1050 "sizeY": sizeY, \1051 "squareLength": squareLength, \1052 "markerLength": markerLength, \1053 "borderBits": borderBits, \1054 "subSizeX": subSizeX, \1055 "subSizeY": subSizeY, \1056 "pageBorderX": pageBorderX, \1057 "pageBorderY": pageBorderY, \1058 }))1059 subSize = None1060 if(subSizeX > 0):1061 if(subSizeY > 0):1062 subSize = (subSizeX, subSizeY)1063 else:1064 subSize = (subSizeX, sizeY)1065 else:1066 if(subSizeY > 0):1067 subSize = (sizeX, subSizeY)1068 else:1069 subSize = None1070 # Gen1071 MarkerPrinter.GenCharucoMarkerImage(args.fileName, args.dictionary, (sizeX, sizeY), squareLength, markerLength, borderBits=borderBits, subSize=subSize, pageBorder = (pageBorderX, pageBorderY))1072 else:...

Full Screen

Full Screen

StackProcessing.py

Source:StackProcessing.py Github

copy

Full Screen

1# -*- coding: utf-8 -*-2"""3Process a image stack in parallel or sequentially4In this toolbox image processing is parallized via splitting a volumetric5image stack into several sub-stacks, typically in z-direction. As most of 6the image processig steps are non-local sub-stacks are created with overlaps 7and the results rejoined accordingly to minimize boundary effects.8Parallel processing is handled via this module.9.. _SubStack:10Sub-Stacks11----------12The parallel processing module creates a dictionary with information on13the sub-stack as follows:14========================== ==================================================15Key Description16========================== ==================================================17``stackId`` id of the sub-stack18``nStacks`` total number of sub-stacks19``source`` source file/folder/pattern of the stack20``x``, ``y``, ``z`` the range of the sub-stack with in the full image21``zCenters`` tuple of the centers of the overlaps22``zCenterIndices`` tuple of the original indices of the centers of 23 the overlaps24``zSubStackCenterIndices`` tuple of the indices of the sub-stack that25 correspond to the overlap centers26========================== ==================================================27For exmaple the :func:`writeSubStack` routine makes uses of this information28to write out only the sub-parts of the image that is will contribute to the29final total image. 30"""31#:copyright: Copyright 2015 by Christoph Kirst, The Rockefeller University, New York City32#:license: GNU, see LICENSE.txt for details.33import sys34import math35import numpy36import pdb37from multiprocessing import Pool38import ClearMap.IO as io39from ClearMap.Utils.ParameterTools import writeParameter40from ClearMap.Utils.ProcessWriter import ProcessWriter;41from ClearMap.Utils.Timer import Timer;42 43def printSubStackInfo(subStack, out = sys.stdout):44 """Print information about the sub-stack45 46 Arguments:47 subStack (dict): the sub-stack info48 out (object): the object to write the information to49 """50 writeParameter(head = "Sub Stack: ", out = out, **subStack);51 out.write('\n');52#define the subroutine for the processing53def _processSubStack(dsr):54 """Helper to process stack in parallel"""55 sf = dsr[0];56 pp = dsr[1];57 sub = dsr[2];58 verbose = dsr[3];59 timer = Timer();60 pw = ProcessWriter(sub["stackId"]);61 62 if verbose:63 pw.write("processing substack " + str(sub["stackId"]) + "/" + str(sub["nStacks"]));64 pw.write("file = " + sub["source"]);65 pw.write("segmentation = " + str(sf));66 pw.write("ranges: x,y,z = " + str(sub["x"]) + "," + str(sub["y"]) + "," + str(sub["z"])); 67 68 img = io.readData(sub["source"], x = sub["x"], y = sub["y"], z = sub["z"]);69 70 if verbose:71 pw.write(timer.elapsedTime(head = 'Reading data of size ' + str(img.shape)));72 73 timer.reset();74 seg = sf(img, subStack = sub, out = pw, **pp); 75 if verbose: 76 pw.write(timer.elapsedTime(head = 'Processing substack of size ' + str(img.shape)));77 78 return seg;79def writeSubStack(filename, img, subStack = None):80 """Write the non-redundant part of a sub-stack to disk81 82 The routine is used to write out images when porcessed in parallel.83 It assumes that the filename is a patterned file name.84 85 Arguments:86 filename (str or None): file name pattern as described in 87 :mod:`~ClearMap.Io.FileList`, if None return as array88 img (array): image data of sub-stack89 subStack (dict or None): sub-stack information, if None write entire image90 see :ref:`SubStack`91 92 Returns:93 str or array: the file name pattern or image94 """95 96 if not subStack is None:97 ii = subStack["zSubStackCenterIndices"][0];98 ee = subStack["zSubStackCenterIndices"][1];99 si = subStack["zCenterIndices"][0];100 else:101 si = 0;102 ii = 0;103 ee = -1;104 105 return io.writeData(filename, img[:,:,ii:ee], startIndex = si ); 106def joinPoints(results, subStacks = None, shiftPoints = True, **args):107 """Joins a list of points obtained from processing a stack in chunks108 109 Arguments:110 results (list): list of point results from the individual sub-processes111 subStacks (list or None): list of all sub-stack information, see :ref:`SubStack`112 shiftPoints (bool): if True shift points to refer to origin of the image stack considered113 when range specification is given. If False, absolute 114 position in entire image stack.115 116 Returns:117 tuple: joined points, joined intensities118 """119 120 nchunks = len(results);121 pointlist = [results[i][0] for i in range(nchunks)];122 intensities = [results[i][1] for i in range(nchunks)]; 123 124 results = [];125 resultsi = [];126 for i in range(nchunks):127 cts = pointlist[i];128 cti = intensities[i];129 if cts.size > 0:130 cts[:,2] += subStacks[i]["z"][0];131 iid = numpy.logical_and(subStacks[i]["zCenters"][0] <= cts[:,2] , cts[:,2] < subStacks[i]["zCenters"][1]);132 cts = cts[iid,:];133 results.append(cts);134 if not cti is None:135 cti = cti[iid];136 resultsi.append(cti);137 138 if results == []:139 if not intensities is None:140 return (numpy.zeros((0,3)), numpy.zeros((0)));141 else:142 return numpy.zeros((0,3))143 else:144 points = numpy.concatenate(results);145 146 if shiftPoints:147 points = points + io.pointShiftFromRange(io.dataSize(subStacks[0]["source"]), x = subStacks[0]["x"], y = subStacks[0]["y"], z = 0);148 else:149 points = points - io.pointShiftFromRange(io.dataSize(subStacks[0]["source"]), x = 0, y = 0, z = subStacks[0]["z"]); #absolute offset is added initially via zranges !150 151 if intensities is None:152 return points;153 else:154 return (points, numpy.concatenate(resultsi));155def calculateChunkSize(size, processes = 2, chunkSizeMax = 100, chunkSizeMin = 30, chunkOverlap = 15, chunkOptimization = True, chunkOptimizationSize = all, verbose = True):156 """Calculates the chunksize and other info for parallel processing157 158 The sub stack information is described in :ref:`SubStack` 159 160 Arguments:161 processes (int): number of parallel processes162 chunkSizeMax (int): maximal size of a sub-stack163 chunkSizeMin (int): minial size of a sub-stack164 chunkOverlap (int): minimal sub-stack overlap165 chunkOptimization (bool): optimize chunck sizes to best fit number of processes166 chunkOptimizationSize (bool or all): if True only decrease the chunk size when optimizing167 verbose (bool): print information on sub-stack generation168 169 Returns:170 tuple: number of chunks, z-ranges of each chunk, z-centers in overlap regions171 """172 173 pre = "ChunkSize: ";174 175 #calcualte chunk sizes176 chunksize = chunkSizeMax;177 nchunks = int(math.ceil((size - chunksize) / (1. * (chunksize - chunkOverlap)) + 1)); 178 if nchunks <= 0:179 nchunks = 1; 180 chunksize = (size + (nchunks-1) * chunkOverlap) / nchunks;181 182 if verbose:183 print pre + "Estimated chunk size " + str(chunksize) + " in " + str(nchunks) + " chunks!";184 185 if nchunks == 1:186 return 1, [(0, chunksize)], [0, chunksize]187 188 #optimize number of chunks wrt to number of processors189 if chunkOptimization:190 np = nchunks % processes;191 if np != 0:192 if chunkOptimizationSize == all:193 if np < processes / 2.0:194 chunkOptimizationSize = True;195 else:196 chunkOptimizationSize = False;197 198 if verbose:199 print pre + "Optimizing chunk size to fit number of processes!"200 201 if not chunkOptimizationSize:202 #try to deccrease chunksize / increase chunk number to fit distribution on processors203 nchunks = nchunks - np + processes;204 chunksize = (size + (nchunks-1) * chunkOverlap) / nchunks;205 206 if verbose:207 print pre + "Optimized chunk size decreased to " + str(chunksize) + " in " + str(nchunks) + " chunks!";208 209 else:210 if nchunks != np:211 #try to decrease chunk number to fit processors212 nchunks = nchunks - np;213 chunksize = (size + (nchunks-1) * chunkOverlap) / nchunks;214 215 if verbose:216 print pre + "Optimized chunk size increased to " + str(chunksize) + " in " + str(nchunks) + " chunks!";217 218 else:219 if verbose:220 print pre + "Optimized chunk size unchanged " + str(chunksize) + " in " + str(nchunks) + " chunks!";221 222 else:223 if verbose:224 print pre + "Optimized chunk size unchanged " + str(chunksize) + " in " + str(nchunks) + " chunks!";225 226 227 #increase overlap if chunks to small228 chunkSizeMin = min(chunkSizeMin, chunkOverlap);229 if chunksize < chunkSizeMin:230 if verbose: 231 print pre + "Warning: optimal chunk size " + str(chunksize) + " smaller than minimum chunk size " + str(chunkSizeMin) + "!"; 232 chunksize = chunkSizeMin;233 chunkOverlap = math.ceil(chunksize - (size - chunksize) / (nchunks -1));234 235 if verbose: 236 print pre + "Warning: setting chunk overlap to " + str(chunkOverlap) + "!";237 238 #calucalte actual chunk sizes239 chunksizerest = chunksize;240 chunksize = int(math.floor(chunksize));241 chunksizerest = chunksizerest - chunksize;242 243 zranges = [(0, chunksize)];244 zcenters = [0];245 n = 1;246 csr = chunksizerest;247 zhi = chunksize;248 249 while (n < nchunks):250 n += 1;251 252 zhiold = zhi;253 zlo = zhi - chunkOverlap;254 zhi = zlo + chunksize;255 256 csr += chunksizerest;257 if csr >= 1:258 csr = csr - 1;259 zhi += 1;260 261 if n == nchunks: 262 zhi = size;263 264 zranges.append((int(zlo), int(zhi)));265 zcenters.append((zhiold - zlo) / 2. + zlo); 266 267 zcenters.append(size);268 269 if verbose: 270 print zranges271 print pre + "final chunks : " + str(zranges);272 print pre + "final centers: " + str(zcenters);273 274 return nchunks, zranges, zcenters;275def calculateSubStacks(source, z = all, x = all, y = all, **args):276 """Calculates the chunksize and other info for parallel processing and returns a list of sub-stack objects277 278 The sub-stack information is described in :ref:`SubStack` 279 280 Arguments:281 source (str): image source282 x,y,z (tuple or all): range specifications283 processes (int): number of parallel processes284 chunkSizeMax (int): maximal size of a sub-stack285 chunkSizeMin (int): minial size of a sub-stack286 chunkOverlap (int): minimal sub-stack overlap287 chunkOptimization (bool): optimize chunck sizes to best fit number of processes288 chunkOptimizationSize (bool or all): if True only decrease the chunk size when optimizing289 verbose (bool): print information on sub-stack generation290 291 Returns:292 list: list of sub-stack objects293 """ 294 295 #determine z ranges296 fs = io.dataSize(source);297 zs = fs[2];298 zr = io.toDataRange(zs, r = z);299 nz = zr[1] - zr[0];300 301 #calculate optimal chunk sizes302 nchunks, zranges, zcenters = calculateChunkSize(nz, **args);303 304 #adjust for the zrange305 zcenters = [c + zr[0] for c in zcenters];306 zranges = [(zc[0] + zr[0], zc[1] + zr[0]) for zc in zranges];307 308 #create substacks309 subStacks = [];310 indexlo = zr[0];311 312 for i in range(nchunks):313 314 indexhi = int(round(zcenters[i+1]));315 if indexhi > zr[1] or i == nchunks - 1:316 indexhi = zr[1];317 318 zs = zranges[i][1] - zranges[i][0];319 320 subStacks.append({"stackId" : i, "nStacks" : nchunks, 321 "source" : source, "x" : x, "y" : y, "z" : zranges[i], 322 "zCenters" : (zcenters[i], zcenters[i+1]),323 "zCenterIndices" : (indexlo, indexhi),324 "zSubStackCenterIndices" : (indexlo - zranges[i][0], zs - (zranges[i][1] - indexhi))});325 326 indexlo = indexhi; # + 1;327 328 return subStacks;329 330def noProcessing(img, **parameter):331 """Perform no image processing at all and return original image332 333 Used as the default functon in :func:`parallelProcessStack` and334 :func:`sequentiallyProcessStack`.335 336 Arguments:337 img (array): imag338 339 Returns:340 (array): the original image341 """342def parallelProcessStack(source, x = all, y = all, z = all, sink = None,343 processes = 2, chunkSizeMax = 100, chunkSizeMin = 30, chunkOverlap = 15,344 chunkOptimization = True, chunkOptimizationSize = all, 345 function = noProcessing, join = joinPoints, verbose = True, **parameter):346 """Parallel process a image stack347 348 Main routine that distributes image processing on paralllel processes.349 350 Arguments:351 source (str): image source352 x,y,z (tuple or all): range specifications353 sink (str or None): destination for the result354 processes (int): number of parallel processes355 chunkSizeMax (int): maximal size of a sub-stack356 chunkSizeMin (int): minial size of a sub-stack357 chunkOverlap (int): minimal sub-stack overlap358 chunkOptimization (bool): optimize chunck sizes to best fit number of processes359 chunkOptimizationSize (bool or all): if True only decrease the chunk size when optimizing360 function (function): the main image processing script361 join (function): the fuction to join the results from the image processing script362 verbose (bool): print information on sub-stack generation363 364 Returns:365 str or array: results of the image processing366 """ 367 368 subStacks = calculateSubStacks(source, x = x, y = y, z = z, 369 processes = processes, chunkSizeMax = chunkSizeMax, chunkSizeMin = chunkSizeMin, chunkOverlap = chunkOverlap,370 chunkOptimization = chunkOptimization, chunkOptimizationSize = chunkOptimizationSize, verbose = verbose);371 372 nSubStacks = len(subStacks);373 if verbose:374 print "Number of SubStacks: %d" % nSubStacks;375 376 #for i in range(nSubStacks):377 # self.printSubStackInfo(subStacks[i]);378 379 argdata = [];380 for i in range(nSubStacks):381 argdata.append((function, parameter, subStacks[i], verbose)); 382 #print argdata383 384 # process in parallel385 pool = Pool(processes = processes); 386 results = pool.map(_processSubStack, argdata);387 388 print '=========== results';389 print results;390 391 #join the results392 results = join(results, subStacks = subStacks, **parameter);393 #write / or return 394 return io.writePoints(sink, results);395def sequentiallyProcessStack(source, x = all, y = all, z = all, sink = None,396 chunkSizeMax = 100, chunkSizeMin = 30, chunkOverlap = 15,397 function = noProcessing, join = joinPoints, verbose = False, **parameter):398 """Sequential image processing on a stack399 400 Main routine that sequentially processes a large image on sub-stacks.401 402 Arguments:403 source (str): image source404 x,y,z (tuple or all): range specifications405 sink (str or None): destination for the result406 processes (int): number of parallel processes407 chunkSizeMax (int): maximal size of a sub-stack408 chunkSizeMin (int): minial size of a sub-stack409 chunkOverlap (int): minimal sub-stack overlap410 chunkOptimization (bool): optimize chunck sizes to best fit number of processes411 chunkOptimizationSize (bool or all): if True only decrease the chunk size when optimizing412 function (function): the main image processing script413 join (function): the fuction to join the results from the image processing script414 verbose (bool): print information on sub-stack generation415 416 Returns:417 str or array: results of the image processing418 """ 419 #determine z ranges 420 421 subStacks = calculateSubStacks(source, x = x, y = y, z = z, 422 processes = 1, chunkSizeMax = chunkSizeMax, chunkSizeMin = chunkSizeMin, chunkOverlap = chunkOverlap, 423 chunkOptimization = False, verbose = verbose);424 425 nSubStacks = len(subStacks);426 #print nSubStacks; 427 428 argdata = [];429 for i in range(nSubStacks):430 argdata.append((function, parameter, subStacks[i], verbose)); 431 432 #run sequentially433 results = [];434 for i in range(nSubStacks):435 results.append(_processSubStack(argdata[i]));436 437 #join the results438 results = join(results, subStacks = subStacks, **parameter);439 440 #write / or return 441 return io.writePoints(sink, results);442### Pickle does not like classes:443## sub stack information444#class SubStack(object):445# """Class containing all info of a sub stack usefull for the image processing and result joining functions"""446# 447# # sub stack id448# stackId = None;449# 450# # number of stacks451# nStacks = None;452# 453# # tuple of x,y,z range of this sub stack454# z = all; 455# x = all;456# y = all;457# 458# #original source459# source = None; 460# 461# # tuple of center point of the overlaping regions462# zCenters = None;463# 464# # tuple of z indices that would generate full image without overlaps465# zCenterIndices = None;466# 467# # tuple of z indices in the sub image as returned by readData that would generate full image without overlaps468# zSubCenterIndices = None;469# 470# 471# def __init__(slf, stackId = 0, nStacks = 1, source = None, x = all, y = all, z = all, zCenters = all, zCenterIndices = all):472# slf.stackId = stackId;473# slf.nStacks = nStacks;474# slf.source = source; 475# slf.x = x;476# slf.y = y;477# slf.z = z;478# slf.zCenters = zCenters;479# slf.zCenterIndices = zCenterIndices;480# if not zCenterIndices is all and not z is all:481# slf.zSubCenterIndices = (c - z[0] for c in zCenterIndices);482# else:483# slf.zSubCenterIndices = all;484# 485# 486#def printSubStackInfo(slf, out = sys.stdout):487# out.write("Sub Stack: %d / %d\n" % (slf.stackId, slf.nStacks));488# out.write("source: %s\n" % slf.source);489# out.write("x,y,z: %s, %s, %s\n" % (str(slf.x), str(slf.y), str(slf.z)));490# out.write("zCenters: %s\n" % str(slf.zCenters)); ...

Full Screen

Full Screen

category_data.py

Source:category_data.py Github

copy

Full Screen

1#!/usr/bin/env python2# encoding: utf-83row_data = [4 {5 'sub_categorys': [6 {7 'sub_categorys': [8 {9 'code': 'yr',10 'name': '羊肉'11 },12 {13 'code': 'ql',14 'name': '禽类'15 },16 {17 'code': 'zr',18 'name': '猪肉'19 },20 {21 'code': 'nr',22 'name': '牛肉'23 }24 ],25 'code': 'jprl',26 'name': '精品肉类'27 },28 {29 'sub_categorys': [30 {31 'code': 'cb',32 'name': '参鲍'33 },34 {35 'code': 'yu',36 'name': '鱼'37 },38 {39 'code': 'xia',40 'name': '虾'41 },42 {43 'code': 'xb',44 'name': '蟹/贝'45 }46 ],47 'code': 'hxsc',48 'name': '海鲜水产'49 },50 {51 'sub_categorys': [52 {53 'code': 'xhd_xyd',54 'name': '松花蛋/咸鸭蛋'55 },56 {57 'code': 'jd',58 'name': '鸡蛋'59 }60 ],61 'code': 'dzp',62 'name': '蛋制品'63 },64 {65 'sub_categorys': [66 {67 'code': 'sc',68 'name': '生菜'69 },70 {71 'code': 'bc',72 'name': '菠菜'73 },74 {75 'code': 'yj',76 'name': '圆椒'77 },78 {79 'code': 'xlh',80 'name': '西兰花'81 }82 ],83 'code': 'ycl',84 'name': '叶菜类'85 },86 {87 'sub_categorys': [88 ],89 'code': 'gjl',90 'name': '根茎类'91 },92 {93 'sub_categorys': [94 ],95 'code': 'qgl',96 'name': '茄果类'97 },98 {99 'sub_categorys': [100 ],101 'code': 'jgl',102 'name': '菌菇类'103 },104 {105 'sub_categorys': [106 ],107 'code': 'jksx',108 'name': '进口生鲜'109 }110 ],111 'code': 'sxsp',112 'name': '生鲜食品'113 },114 {115 'sub_categorys': [116 {117 'sub_categorys': [118 {119 'code': 'wly',120 'name': '五粮液'121 },122 {123 'code': 'lzlj',124 'name': '泸州老窖'125 },126 {127 'code': 'mt',128 'name': '茅台'129 }130 ],131 'code': 'bk',132 'name': '白酒'133 },134 {135 'sub_categorys': [136 ],137 'code': 'ptj',138 'name': '葡萄酒'139 },140 {141 'sub_categorys': [142 ],143 'code': 'yj',144 'name': '洋酒'145 },146 {147 'sub_categorys': [148 ],149 'code': 'pj',150 'name': '啤酒'151 },152 {153 'sub_categorys': [154 {155 'code': 'qtpp',156 'name': '其他品牌'157 },158 {159 'code': 'hj',160 'name': '黄酒'161 },162 {163 'code': 'ysj',164 'name': '养生酒'165 }166 ],167 'code': 'qtjp',168 'name': '其他酒品'169 },170 {171 'sub_categorys': [172 ],173 'code': 'yls',174 'name': '饮料/水'175 },176 {177 'sub_categorys': [178 {179 'code': 'bld',180 'name': '白兰地'181 },182 {183 'code': 'wsj',184 'name': '威士忌'185 }186 ],187 'code': 'hj',188 'name': '红酒'189 }190 ],191 'code': 'jsyl',192 'name': '酒水饮料'193 },194 {195 'sub_categorys': [196 {197 'sub_categorys': [198 {199 'code': '其他食用油',200 'name': '其他食用油'201 },202 {203 'code': '菜仔油',204 'name': '菜仔油'205 },206 {207 'code': '花生油',208 'name': '花生油'209 },210 {211 'code': '橄榄油',212 'name': '橄榄油'213 },214 {215 'code': '礼盒',216 'name': '礼盒'217 }218 ],219 'code': '食用油',220 'name': '食用油'221 },222 {223 'sub_categorys': [224 {225 'code': '面粉/面条',226 'name': '面粉/面条'227 },228 {229 'code': '大米',230 'name': '大米'231 },232 {233 'code': '意大利面',234 'name': '意大利面'235 }236 ],237 'code': '米面杂粮',238 'name': '米面杂粮'239 },240 {241 'sub_categorys': [242 {243 'code': '调味油/汁',244 'name': '调味油/汁'245 },246 {247 'code': '酱油/醋',248 'name': '酱油/醋'249 }250 ],251 'code': '厨房调料',252 'name': '厨房调料'253 },254 {255 'sub_categorys': [256 ],257 'code': '南北干货',258 'name': '南北干货'259 },260 {261 'sub_categorys': [262 ],263 'code': '方便速食',264 'name': '方便速食'265 },266 {267 'sub_categorys': [268 ],269 'code': '调味品',270 'name': '调味品'271 }272 ],273 'code': '粮油副食',274 'name': '粮油副食'275 },276 {277 'sub_categorys': [278 {279 'sub_categorys': [280 {281 'code': '西红柿',282 'name': '西红柿'283 },284 {285 'code': '韭菜',286 'name': '韭菜'287 },288 {289 'code': '青菜',290 'name': '青菜'291 }292 ],293 'code': '有机蔬菜',294 'name': '有机蔬菜'295 },296 {297 'sub_categorys': [298 {299 'code': '甘蓝',300 'name': '甘蓝'301 },302 {303 'code': '胡萝卜',304 'name': '胡萝卜'305 },306 {307 'code': '黄瓜',308 'name': '黄瓜'309 }310 ],311 'code': '精选蔬菜',312 'name': '精选蔬菜'313 },314 {315 'sub_categorys': [316 {317 'code': '火龙果',318 'name': '火龙果'319 },320 {321 'code': '菠萝蜜',322 'name': '菠萝蜜'323 },324 {325 'code': '奇异果',326 'name': '奇异果'327 }328 ],329 'code': '进口水果',330 'name': '进口水果'331 },332 {333 'sub_categorys': [334 {335 'code': '水果礼盒',336 'name': '水果礼盒'337 },338 {339 'code': '苹果',340 'name': '苹果'341 },342 {343 'code': '雪梨',344 'name': '雪梨'345 }346 ],347 'code': '国产水果',348 'name': '国产水果'349 }350 ],351 'code': '蔬菜水果',352 'name': '蔬菜水果'353 },354 {355 'sub_categorys': [356 {357 'sub_categorys': [358 {359 'code': '果冻',360 'name': '果冻'361 },362 {363 'code': '枣类',364 'name': '枣类'365 },366 {367 'code': '蜜饯',368 'name': '蜜饯'369 },370 {371 'code': '肉类零食',372 'name': '肉类零食'373 },374 {375 'code': '坚果炒货',376 'name': '坚果炒货'377 }378 ],379 'code': '休闲零食',380 'name': '休闲零食'381 },382 {383 'sub_categorys': [384 {385 'code': '创意喜糖',386 'name': '创意喜糖'387 },388 {389 'code': '口香糖',390 'name': '口香糖'391 },392 {393 'code': '软糖',394 'name': '软糖'395 },396 {397 'code': '棒棒糖',398 'name': '棒棒糖'399 }400 ],401 'code': '糖果',402 'name': '糖果'403 },404 {405 'sub_categorys': [406 {407 'code': '夹心巧克力',408 'name': '夹心巧克力'409 },410 {411 'code': '白巧克力',412 'name': '白巧克力'413 },414 {415 'code': '松露巧克力',416 'name': '松露巧克力'417 },418 {419 'code': '黑巧克力',420 'name': '黑巧克力'421 }422 ],423 'code': '巧克力',424 'name': '巧克力'425 },426 {427 'sub_categorys': [428 {429 'code': '牛肉干',430 'name': '牛肉干'431 },432 {433 'code': '猪肉脯',434 'name': '猪肉脯'435 },436 {437 'code': '牛肉粒',438 'name': '牛肉粒'439 },440 {441 'code': '猪肉干',442 'name': '猪肉干'443 }444 ],445 'code': '肉干肉脯/豆干',446 'name': '肉干肉脯/豆干'447 },448 {449 'sub_categorys': [450 {451 'code': '鱿鱼足',452 'name': '鱿鱼足'453 },454 {455 'code': '鱿鱼丝',456 'name': '鱿鱼丝'457 },458 {459 'code': '墨鱼/乌贼',460 'name': '墨鱼/乌贼'461 },462 {463 'code': '鱿鱼仔',464 'name': '鱿鱼仔'465 },466 {467 'code': '鱿鱼片',468 'name': '鱿鱼片'469 }470 ],471 'code': '鱿鱼丝/鱼干',472 'name': '鱿鱼丝/鱼干'473 }474 ],475 'code': '休闲食品',476 'name': '休闲食品'477 },478 {479 'sub_categorys': [480 {481 'sub_categorys': [482 ],483 'code': '进口奶品',484 'name': '进口奶品'485 },486 {487 'sub_categorys': [488 ],489 'code': '国产奶品',490 'name': '国产奶品'491 },492 {493 'sub_categorys': [494 ],495 'code': '奶粉',496 'name': '奶粉'497 },498 {499 'sub_categorys': [500 ],501 'code': '有机奶',502 'name': '有机奶'503 },504 {505 'sub_categorys': [506 ],507 'code': '原料奶',508 'name': '原料奶'509 }510 ],511 'code': '奶类食品',512 'name': '奶类食品'513 },514 {515 'sub_categorys': [516 {517 'sub_categorys': [518 ],519 'code': '菌菇类',520 'name': '菌菇类'521 },522 {523 'sub_categorys': [524 ],525 'code': '腌干海产',526 'name': '腌干海产'527 },528 {529 'sub_categorys': [530 ],531 'code': '汤料',532 'name': '汤料'533 },534 {535 'sub_categorys': [536 ],537 'code': '豆类',538 'name': '豆类'539 },540 {541 'sub_categorys': [542 ],543 'code': '干菜/菜干',544 'name': '干菜/菜干'545 },546 {547 'sub_categorys': [548 ],549 'code': '干果/果干',550 'name': '干果/果干'551 },552 {553 'sub_categorys': [554 ],555 'code': '豆制品',556 'name': '豆制品'557 },558 {559 'sub_categorys': [560 ],561 'code': '腊味',562 'name': '腊味'563 }564 ],565 'code': '天然干货',566 'name': '天然干货'567 },568 {569 'sub_categorys': [570 {571 'sub_categorys': [572 ],573 'code': '白茶',574 'name': '白茶'575 },576 {577 'sub_categorys': [578 ],579 'code': '红茶',580 'name': '红茶'581 },582 {583 'sub_categorys': [584 ],585 'code': '绿茶',586 'name': '绿茶'587 }588 ],589 'code': '精选茗茶',590 'name': '精选茗茶'591 }...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run autotest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful