1# -*- coding: utf-8 -*-
2# ------------------------------------------------------------------------------
3# Name:          timeGraphs.py
4# Purpose:       time how long it takes to run music21 commands
5#
6# Authors:       Michael Scott Cuthbert
7#                Christopher Ariza
8#
9# Copyright:    Copyright © 2009-2020 Michael Scott Cuthbert and the music21 Project
10# License:      BSD, see license.txt
11# ------------------------------------------------------------------------------
12# pragma: no cover
13import cProfile
14import pstats
15# import time
16
17import music21
18# from music21.common.objects import Timer
19
20
21
22class Test:
23    '''Base class for timed tests that need music21 imported
24    '''
25
26
27# ------------------------------------------------------------------------------
28class TestTimeHumdrum(Test):
29    def testFocus(self):
30        # pylint: disable=expression-not-assigned
31        # noinspection PyStatementEffect
32        music21.humdrum.parseData(music21.humdrum.humdrumTestFiles.mazurka6
33                                  ).stream
34
35class TestTimeMozart(Test):
36    def testFocus(self):
37        music21.converter.parse(music21.corpus.getWork('k155')[0])
38
39class TestTimeCapua1(Test):
40    def testFocus(self):
41        c1 = music21.trecento.capua.Test()
42        c1.testRunPiece()
43
44class TestTimeCapua2(Test):
45    def testFocus(self):
46        music21.trecento.capua.ruleFrequency()
47
48class TestTimeIsmir(Test):
49    def testFocus(self):
50        music21.corpus.parse('bach/bwv248')
51
52
53class TestMakeMeasures(Test):
54    def __init__(self):
55        super().__init__()
56        self.s = music21.stream.Stream()
57        for i in range(10):
58            n = music21.note.Note()
59            self.s.append(n)
60
61    def testFocus(self):
62        self.s.makeMeasures()
63
64
65class TestMakeTies(Test):
66    def __init__(self):
67        super().__init__()
68
69        self.s = music21.stream.Stream()
70        for i in range(100):
71            n = music21.note.Note()
72            n.quarterLength = 8
73            self.s.append(n)
74        self.s = self.s.makeMeasures()
75
76    def testFocus(self):
77        self.s.makeTies(inPlace=True)
78
79
80class TestMakeBeams(Test):
81    def __init__(self):
82        super().__init__()
83
84        self.s = music21.stream.Stream()
85        for i in range(100):
86            n = music21.note.Note()
87            n.quarterLength = 0.25
88            self.s.append(n)
89        self.s = self.s.makeMeasures()
90
91    def testFocus(self):
92        self.s.makeBeams(inPlace=True)
93
94
95class TestMakeAccidentals(Test):
96    def __init__(self):
97
98        super().__init__()
99
100        self.s = music21.stream.Stream()
101        for i in range(100):
102            n = music21.note.Note()
103            n.quarterLength = 0.25
104            self.s.append(n)
105        self.s = self.s.makeMeasures()
106
107    def testFocus(self):
108        self.s.makeAccidentals(inPlace=True)
109
110
111class TestMusicXMLOutput(Test):
112    def __init__(self):
113        self.s = music21.stream.Stream()
114        for i in range(100):
115            n = music21.note.Note()
116            n.quarterLength = 1.5
117            self.s.append(n)
118
119    def testFocus(self):
120        self.s.write('musicxml')
121
122
123class TestMusicXMLOutputParts(Test):
124    '''
125    This tries to isolate a problem whereby part
126    creation is much faster than score creation.
127    '''
128    def __init__(self):
129        from music21 import corpus
130
131        self.s = corpus.parse('bach/bwv66.6', forceSource=True)
132        # self.s = corpus.parse('beethoven/opus59no2/movement3', forceSource=True)
133
134    def testFocus(self):
135        for p in self.s.parts:
136            p.write('musicxml')
137
138
139
140
141class TestCreateTimeSignature(Test):
142
143    def __init__(self):
144        from music21.test import testPerformance
145        self.t = testPerformance.Test()
146
147    def testFocus(self):
148        # create 500 time signatures
149        self.t.runCreateTimeSignatures()
150
151
152
153class TestCreateDurations(Test):
154
155    def __init__(self):
156        from music21.test import testPerformance
157        self.t = testPerformance.Test()
158
159    def testFocus(self):
160        # create 500 time signatures
161        self.t.runCreateDurations()
162
163
164
165
166class TestParseABC(Test):
167
168    def __init__(self):
169        from music21.test import testPerformance
170        self.t = testPerformance.Test()
171
172    def testFocus(self):
173        # create 500 time signatures
174        self.t.runParseABC()
175
176
177
178
179
180
181class TestGetContextByClassA(Test):
182
183    def __init__(self):
184        from music21 import corpus
185        from music21 import meter
186        from music21 import clef
187        from music21 import key
188        self.s = corpus.parse('bwv66.6')
189        self.m = meter
190        self.c = clef
191        self.k = key
192
193    def testFocus(self):
194        meter = self.m
195        clef = self.c
196        key = self.k
197        for p in self.s.parts:
198            for m in p.getElementsByClass('Measure'):
199                m.getContextByClass(clef.Clef)
200                m.getContextByClass(meter.TimeSignature)
201                m.getContextByClass(key.KeySignature)
202                for n in m.notesAndRests:
203                    n.getContextByClass(clef.Clef)
204                    n.getContextByClass(meter.TimeSignature)
205                    n.getContextByClass(key.KeySignature)
206
207
208class TestParseRNText(Test):
209
210    def __init__(self):
211        from music21.test import testPerformance
212        self.t = testPerformance.Test()
213
214    def testFocus(self):
215        self.t.runParseMonteverdiRNText()
216
217
218# ------------------------------------------------------------------------------
219class TestMusicXMLMultiPartOutput(Test):
220
221    def __init__(self):
222        from music21 import note
223        from music21 import stream
224        self.s = stream.Score()
225        for i in range(10):  # parts
226            p = stream.Part()
227            for j in range(10):  # measures
228                m = stream.Measure()
229                m.append(note.Note(type='quarter'))
230                p.append(m)
231            p._mutable = False
232            self.s.insert(0, p)
233
234        for obj in self.s.recurse(streamsOnly=True):
235            obj._mutable = False
236
237        # self.s.show()
238
239    def testFocus(self):
240        self.s.write('musicxml')
241
242
243class TestCommonContextSearches(Test):
244
245    def __init__(self):
246        from music21 import corpus
247        self.s = corpus.parse('bwv66.6')
248
249    def testFocus(self):
250        self.s.parts[0].getElementsByClass(
251            'Measure')[3].getContextByClass('TimeSignature')
252
253
254class TestBigMusicXML(Test):
255
256    def __init__(self):
257        from music21 import corpus
258        self.s = corpus.parse('opus41no1')
259
260    def testFocus(self):
261        self.s.write('musicxml')
262
263
264class TestGetElementsByClassA(Test):
265
266    def __init__(self):
267        from music21 import corpus
268        self.s = corpus.parse('bwv66.6')
269
270    def testFocus(self):
271        len(self.s.flatten().notes)
272
273
274
275class TestGetElementsByClassB(Test):
276
277    def __init__(self):
278        from music21 import stream
279        from music21 import note
280        from music21 import clef
281        from music21 import meter
282        from music21 import chord
283        self.s = stream.Stream()
284        self.s.repeatAppend(note.Note(), 300)
285        self.s.repeatAppend(note.Rest(), 300)
286        self.s.repeatAppend(chord.Chord(), 300)
287        self.s.repeatInsert(meter.TimeSignature(), [0, 50, 100, 150])
288        self.s.repeatInsert(clef.BassClef(), [0, 50, 100, 150])
289
290    def testFocus(self):
291        for i in range(20):
292            self.s.getElementsByClass(['Rest'])
293            self.s.getElementsByClass(['Note'])
294            self.s.getElementsByClass(['GeneralNote'])
295            self.s.getElementsByClass(['NotRest'])
296            self.s.getElementsByClass(['BassClef'])
297            self.s.getElementsByClass(['Clef'])
298            self.s.getElementsByClass(['TimeSignature'])
299
300
301class TestGetContextByClassB(Test):
302    def __init__(self):
303        from music21 import meter
304        from music21 import note
305        from music21 import stream
306
307        self.s = stream.Score()
308
309        p1 = stream.Part()
310        m1 = stream.Measure()
311        m1.repeatAppend(note.Note(), 3)
312        m1.timeSignature = meter.TimeSignature('3/4')
313        m2 = stream.Measure()
314        m2.repeatAppend(note.Note(), 3)
315        p1.append(m1)
316        p1.append(m2)
317
318        p2 = stream.Part()
319        m3 = stream.Measure()
320        m3.timeSignature = meter.TimeSignature('3/4')
321        m3.repeatAppend(note.Note(), 3)
322        m4 = stream.Measure()
323        m4.repeatAppend(note.Note(), 3)
324        p2.append(m3)
325        p2.append(m4)
326
327        self.s.insert(0, p1)
328        self.s.insert(0, p2)
329
330        p3 = stream.Part()
331        m5 = stream.Measure()
332        m5.timeSignature = meter.TimeSignature('3/4')
333        m5.repeatAppend(note.Note(), 3)
334        m6 = stream.Measure()
335        m6.repeatAppend(note.Note(), 3)
336        p3.append(m5)
337        p3.append(m6)
338
339        p4 = stream.Part()
340        m7 = stream.Measure()
341        m7.timeSignature = meter.TimeSignature('3/4')
342        m7.repeatAppend(note.Note(), 3)
343        m8 = stream.Measure()
344        m8.repeatAppend(note.Note(), 3)
345        p4.append(m7)
346        p4.append(m8)
347
348        self.s.insert(0, p3)
349        self.s.insert(0, p4)
350
351        # self.targetMeasures = m4
352        self.targetNoteA = m4._elements[-1]  # last element is a note
353        self.targetNoteB = m1._elements[-1]  # last element is a note
354
355    def testFocus(self):
356        # post = self.targetNoteA.getContextByClass('TimeSignature')
357        self.targetNoteA.previous('TimeSignature')
358
359
360
361class TestMeasuresA(Test):
362
363    def __init__(self):
364        from music21 import corpus
365        self.s = corpus.parse('symphony94/02')
366
367    def testFocus(self):
368        self.s.measures(3, 10)
369
370
371class TestMeasuresB(Test):
372    def __init__(self):
373        from music21 import stream
374        from music21 import note
375        from music21 import meter
376
377        self.s = stream.Score()
378        for j in [1]:
379            p = stream.Part()
380            for mn in range(10):
381                m = stream.Measure()
382                if mn == 0:
383                    m.timeSignature = meter.TimeSignature('3/4')
384                for i in range(3):
385                    m.append(note.Note())
386                p.append(m)
387            self.s.insert(0, p)
388        # self.s.show()
389
390    def testFocus(self):
391        self.s.measures(3, 6)
392
393
394class TestGetWork(Test):
395
396    def testFocus(self):
397        music21.corpus.getWork('bach/bwv66.6')
398
399
400class TestImportCorpus3(Test):
401    def __init__(self):
402        # to put the path cache in.
403        music21.corpus.getWork('bach/bwv66.6')
404
405    def testFocus(self):
406        music21.corpus.parse('bach/bwv1.6', forceSource=True)
407
408
409class TestImportPiano(Test):
410    def __init__(self):
411        # to put the path cache in.
412        music21.corpus.getWork('cpebach')
413
414    def testFocus(self):
415        music21.corpus.parse('cpebach', forceSource=True)
416
417
418class TestRomantextParse(Test):
419    def __init__(self):
420        from music21.romanText import testFiles as tf
421        self.converter = music21.converter
422        self.tf = tf
423
424    def testFocus(self):
425        self.converter.parse(self.tf.monteverdi_3_13)
426
427
428def main(TestClass):
429    t = TestClass()
430    with cProfile.Profile() as pr:
431        t.testFocus()
432
433    stats = pstats.Stats(pr)
434    stats.sort_stats(pstats.SortKey.CUMULATIVE)
435    stats.print_stats(0.3)
436
437
438if __name__ == '__main__':
439    main(TestImportPiano)
440
441
442