Mercurial > hg > multiomr
comparison MainMultiOMR.py @ 2:46fb79167a61 tip
Main Code
author | Victor Padilla <victor.padilla.mc@gmail.com> |
---|---|
date | Mon, 04 May 2015 22:56:18 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:0f7f611deca4 | 2:46fb79167a61 |
---|---|
1 ''' | |
2 @organization: Lancaster University & University of Leeds | |
3 @version: 1.0 | |
4 Created on 11/12/2014 | |
5 | |
6 @author: Victor Padilla | |
7 @contact: v.padilla@lancaster.ac.uk | |
8 | |
9 The application can be run through command line (without windows interface) using | |
10 MainMultiOMR library | |
11 | |
12 ''' | |
13 import logging | |
14 import time | |
15 import os | |
16 import gc | |
17 import sys | |
18 from subprocess import Popen | |
19 from music21 import stream | |
20 from music21 import converter | |
21 from Process import PipelineAlignment | |
22 from Process import Voting | |
23 from Process import SymbolConversion | |
24 from Process import FullScoreAlignment | |
25 from Automatism import BatchOMR | |
26 from Result import ProcessGroundS2 | |
27 from Result import ExcellData | |
28 from Functions import FilesFunctions | |
29 from Functions import MeasureFunctions | |
30 from Alignment import NWunsch | |
31 import shutil | |
32 | |
33 from Preprocessing import ossia | |
34 from Preprocessing import movements | |
35 from Preprocessing import preomr | |
36 import PythonMagick | |
37 import PyPDF2 | |
38 | |
39 class MainMultiOMR: | |
40 ''' | |
41 main functions to run the Big Data Process. | |
42 They can be called without interface, from another program, for example | |
43 .... | |
44 # instance | |
45 mmOMR=MainMultiOMR() | |
46 | |
47 # run the Big Data process once | |
48 mmOMR.runBigData("C:\\Users\\victor\\Desktop\\data") | |
49 | |
50 # run the Big Data waiting for changes | |
51 mmOMR.runDummyBigData("C:\\Users\\victor\\Desktop\\data") | |
52 | |
53 # run the Big Data Ground process once to get the results | |
54 mmOMR.runBigDataGroung("C:\\Users\\victor\\Desktop\\data") | |
55 | |
56 # run the Big Data Ground waiting for changes | |
57 mmOMR.runDummyBigData("C:\\Users\\victor\\Desktop\\data") | |
58 ''' | |
59 | |
60 def _loadNWunsch(self): | |
61 ''' | |
62 Load Needlemann-Wunsch algorith library by default | |
63 ''' | |
64 a=["foo00"] | |
65 b=["foo000"] | |
66 NWunsch.NWunsch_getSimilarity(a,b) | |
67 #print "Default NWunsch......" | |
68 | |
69 | |
70 def processPDF2TIFF(self,filename): | |
71 pdf_im = PyPDF2.PdfFileReader(file(filename, "rb")) | |
72 npage = pdf_im.getNumPages() | |
73 print('Converting %d pages.' % npage) | |
74 intMovement=0 | |
75 for p in range(npage): | |
76 im = PythonMagick.Image() | |
77 im.density('300') | |
78 print filename | |
79 im.read(str(filename)+'[' + str(p) +']') | |
80 strOut=str(filename) + str(p) | |
81 im.write(strOut+ '.tif') | |
82 | |
83 infile=strOut+ '.tif' | |
84 po = preomr.PreOMR(infile) | |
85 rv = po.split_movements(strOut+'_A.tif', strOut+'_B.tif') | |
86 if rv != None: | |
87 print("new movement was detected at system %d" % (rv,)) | |
88 | |
89 arrFile=filename.split("\\") | |
90 myFile=arrFile.pop() | |
91 path='\\'.join(arrFile) | |
92 print "**********************",path | |
93 if rv==0: | |
94 intMovement+=1 | |
95 dirMovement=path+"\\m"+str(intMovement) | |
96 os.makedirs(dirMovement) | |
97 shutil.copy(strOut+ '.tif', dirMovement+"\\page_"+str(p)+".tif") | |
98 else: | |
99 dirMovement=path+"\\m"+str(intMovement) | |
100 shutil.copy(strOut+ '_A.tif', dirMovement+"\\page_"+str(p)+".tif") | |
101 intMovement+=1 | |
102 dirMovement=path+"\\m"+str(intMovement) | |
103 os.makedirs(dirMovement) | |
104 shutil.copy(strOut+ '_B.tif', dirMovement+"\\page_"+str(p)+".tif") | |
105 | |
106 else: | |
107 shutil.copy(strOut+ '.tif', dirMovement+"\\page_"+str(p)+".tif") | |
108 | |
109 | |
110 | |
111 | |
112 def processOssia(self,rootDir): | |
113 ############################################### | |
114 # @param dirGeneral root movement folder | |
115 for dirname, dirnames, filenames in os.walk(rootDir): | |
116 for f in filenames: | |
117 fname_path = os.path.join(dirname, f) | |
118 if f.endswith(".tif"): | |
119 print fname_path | |
120 | |
121 ossia.process(fname_path, dirname+"\\_"+f) | |
122 # rootApp=os.path.dirname(sys.argv[0]) | |
123 # rootApp=rootApp.replace("\\","/") | |
124 # cwd="python.exe "+rootApp+"/Preprocessing/ossia.py "+fname_path+" "+fname_path | |
125 # | |
126 # print cwd | |
127 # p = Popen(cwd) | |
128 # p.wait() | |
129 # p.communicate() | |
130 # | |
131 | |
132 | |
133 def processMovement(self,dirGeneral): | |
134 ''' | |
135 Process just one movement. The structure should be | |
136 .... | |
137 \\movementName\\fullScore\\XML\\(the .xml files) | |
138 \\parts\\0\\ | |
139 \\1\\ | |
140 \\2\\XML\\(the .xml files) | |
141 | |
142 the result is \\movementName\\finalScore.xml | |
143 | |
144 usage: | |
145 mmOMR=MainMultiOMR() | |
146 mmOMR.processMovement("C:\Users\victor\Desktop\data\k458\Process\m2") | |
147 ''' | |
148 | |
149 | |
150 ff=FilesFunctions() | |
151 subdirnameParts=ff.SubDirPath(dirGeneral+"\\Parts\\") | |
152 fsOMRs_files=ff.getFiles(dirGeneral+"\\fullScore\\XML\\") | |
153 for dirname in subdirnameParts: | |
154 d=dirname+"/XML/" | |
155 urlSplit=dirname.split("\\") | |
156 part=int(urlSplit[-1]) | |
157 partOMRs_files=ff.getFiles(d) | |
158 print "---------S2------------" | |
159 logging.warning("Part:"+str(part)+" "+d) | |
160 self.setResultS2(d,part,fsOMRs_files,partOMRs_files) | |
161 | |
162 print "---------Synchronising scores and parts------------" | |
163 logging.warning("---------Synchronising scores and parts------------:"+dirGeneral) | |
164 #fsOMRs=ff.getOMRs(dirGeneral+"\\fullScore\\XML\\") | |
165 self.__runSynchroScoresAndParts(dirGeneral,fsOMRs_files) | |
166 | |
167 ############################################### | |
168 # @param path folder where the .xml files are | |
169 # @param idPart part number | |
170 # @param fsOMRs array with the full score files processed by music21 | |
171 # @param partOMRs array with the part files processed by music21 | |
172 def setResultS2(self,path,idPart,fsOMRs,partOMRs): | |
173 ''' | |
174 Takes the fullScores (processing the idPart) and parts. | |
175 It writes the result (result.S2.xml) in the dirname | |
176 | |
177 This function process each part independently | |
178 | |
179 usage: | |
180 | |
181 mmOMR=MainMultiOMR() | |
182 ff=FilesFunctions() | |
183 fsOMRs=ff.getOMRs("C:\\Users\\victor\\Desktop\\data\\k458_test\\Process\\m2\\fullScore\\XML") | |
184 partOMRs=ff.getOMRs("C:\\Users\\victor\\Desktop\\data\\k458_test\\Process\\m2\\parts\\0\\XML") | |
185 d="C:\\Users\\victor\\Desktop\\data\\k458_test\\Process\\m2\\parts\\0\\XML" | |
186 mmOMR.setResultS2(d,0,fsOMRs,partOMRs) | |
187 ''' | |
188 | |
189 | |
190 | |
191 pa=PipelineAlignment() | |
192 vote=Voting() | |
193 sc=SymbolConversion() | |
194 ff=FilesFunctions() | |
195 omr_symbolsAlign,betterOmrIds=pa.alignNJ_files(idPart,fsOMRs,partOMRs) | |
196 #The .txt with the OMRs involved (tree) | |
197 ff.writeText(path,betterOmrIds) | |
198 #voting | |
199 | |
200 outVote=vote.vote(omr_symbolsAlign) | |
201 #apply voices if it is needed | |
202 | |
203 outVote=sc.setVoices(outVote) | |
204 #convert to music21 | |
205 resultS2=sc.convertM21(outVote) | |
206 mf=MeasureFunctions() | |
207 #remove blank measures due to the alignment | |
208 resultS2_clean=mf.filterExtraMeasures(resultS2) | |
209 resultS2_clean.write("musicxml", path+'/result.S2.xml') | |
210 | |
211 | |
212 ############################################### | |
213 # @param dirGeneral folder where is the root of the movement | |
214 # @param fsOMRs array with the full score files processed by music21 | |
215 def __runSynchroScoresAndParts(self,dirGeneral,fsOMRs_files): | |
216 ''' | |
217 Takes the fullScores and part files generated to align the final full score | |
218 - dirGeneral is the movement URL | |
219 - fsOMRs is an array with the full scores OMRs processed by music21 | |
220 ''' | |
221 ff=FilesFunctions() | |
222 subdirnameParts=ff.SubDirPath(dirGeneral+"\\parts\\") | |
223 partsNumber=len(subdirnameParts) | |
224 fsa=FullScoreAlignment() | |
225 idCompleteScoreBetter=fsa.getIdBetterOMRFullScore(fsOMRs_files,partsNumber) | |
226 betterFsOMR=ff.getOMR(fsOMRs_files[idCompleteScoreBetter]) | |
227 finalScore=fsa.runSynchronisingMeasuresNJ(subdirnameParts,betterFsOMR) | |
228 betterFsOMR=None | |
229 finalScore.write("musicxml", dirGeneral+'/finalScore.xml') | |
230 finalScore=None | |
231 gc.collect() | |
232 print "----" | |
233 | |
234 | |
235 | |
236 ############################################### | |
237 # @param dirGeneral root movement folder | |
238 def processMovementGround(self,dirGeneral): | |
239 ''' | |
240 Process the result. Just one movement. It takes each OMR file and compare against the ground. | |
241 The differences are written in .XML and .xls | |
242 | |
243 .... | |
244 \\movementName\\fullScore\\XML\\(the .xml files) | |
245 \\parts\\0\\ | |
246 \\1\\ | |
247 \\2\\XML\\(the .xml files) | |
248 | |
249 the file finalScore.xml should be in \\movementName\\finalScore.xml | |
250 the file ground.xml should be in \\movementName\\ground.xml | |
251 | |
252 The final result is written in | |
253 \\movementName\\parts\\resultGeneral.xlsx | |
254 \\fullScore_errors.xml | |
255 | |
256 usage: | |
257 mmOMR=MainMultiOMR() | |
258 mmOMR.processMovementGround("C:\Users\victor\Desktop\data\k458\Process\m2") | |
259 ''' | |
260 percentagesArray=[] | |
261 betterOMRIds=[] | |
262 ff=FilesFunctions() | |
263 subdirname=ff.SubDirPath(dirGeneral+"\\parts\\") | |
264 filesFull=ff.getFiles(dirGeneral+"\\fullScore\\XML\\") | |
265 | |
266 ground=ff.getGround(dirGeneral) | |
267 groundparsed=converter.parse(ground, forceSource=True) | |
268 finalScore=ff.getFinalScore(dirGeneral) | |
269 finalScoreparsed=converter.parse(finalScore, forceSource=True) | |
270 | |
271 | |
272 for dirname in subdirname: | |
273 d=dirname+"/XML/" | |
274 urlSplit=dirname.split("\\") | |
275 part=int(urlSplit[-1]) | |
276 filesPart=ff.getFiles(d) | |
277 files=filesPart+filesFull | |
278 | |
279 print files | |
280 pg=ProcessGroundS2() | |
281 ErrorsMatrix=[] | |
282 percentages=[] | |
283 | |
284 OMRs=[] | |
285 OMRs.append(groundparsed) | |
286 OMRs.append(finalScoreparsed) | |
287 | |
288 | |
289 | |
290 percentage,errors,scoreWithErrors= pg.getSimilarity(OMRs,part) | |
291 ErrorsMatrix.append(errors) | |
292 percentages.append(percentage) | |
293 if not os.path.exists(dirname+"\\Result"): | |
294 os.makedirs(dirname+"\\Result") | |
295 | |
296 scoreWithErrors.write("musicxml", dirname+"\\Result\\result.S2.xml") | |
297 | |
298 for i in range(len(files)): | |
299 try: | |
300 OMRs[1]=ff.getOMR(files[i]) | |
301 percentage,errors,scoreWithErrors= pg.getSimilarity(OMRs,part) | |
302 ErrorsMatrix.append(errors) | |
303 percentages.append(percentage) | |
304 scoreWithErrors.write("musicxml", dirname+"\\Result\\"+os.path.basename(files[i])) | |
305 except: | |
306 print "ERROR OMR READING" | |
307 ErrorsMatrix.append("ERROR OMR READING") | |
308 percentages.append(0) | |
309 | |
310 | |
311 f=open(d+"betterOMR.txt","r") | |
312 betterOMRId=f.readlines() | |
313 f.close() | |
314 betterOMRIds.append(betterOMRId) | |
315 print "betterOMRIds",betterOMRIds | |
316 ed=ExcellData() | |
317 files.insert(0,dirname+"\\Result\\result.S2.xml" ) | |
318 print files | |
319 ed.saveData(ErrorsMatrix,files,percentages) | |
320 percentagesArray.append(percentages) | |
321 | |
322 | |
323 ed=ExcellData() | |
324 ed.saveGlobalData(percentagesArray,dirGeneral,betterOMRIds,files) | |
325 self.__joinErrorParts(dirGeneral) | |
326 print "----------- END ------------" | |
327 | |
328 ################################################################ | |
329 # @param rootDir root folder where all the scores to process are | |
330 def runBigData(self,rootDir): | |
331 ''' | |
332 Checks if there is any folder to process | |
333 If the folder "Process" is written, but the "finalScore.xml" is not, | |
334 runs the procedure | |
335 | |
336 usage | |
337 | |
338 mmOMR=MainMultiOMR() | |
339 d="C:\\Users\\victor\\Desktop\\cach" | |
340 mmOMR.runBigData(d) | |
341 ''' | |
342 ff=FilesFunctions() | |
343 for outWalk in os.walk(rootDir): | |
344 dirName=outWalk[0] | |
345 arrDir=dirName.split("\\") | |
346 if arrDir[-1]=="Process": | |
347 movements=ff.SubDirPath(dirName) | |
348 for movement in movements: | |
349 print movement | |
350 if not os.path.isfile(movement+"\\finalScore.xml"): | |
351 logging.warning("Movement:"+movement+" "+rootDir) | |
352 self.processMovement(movement) | |
353 | |
354 ################################################################ | |
355 # @param rootDir root folder where all the scores to process are | |
356 def runLoopBigData(self,rootDir,adaptOMRs=False): | |
357 ''' | |
358 Infinity loop for processing data | |
359 Checks if there is any folder to process | |
360 If the folder "Process" is written, but the "finalScore.xml" is not, | |
361 runs the procedure | |
362 | |
363 usage | |
364 | |
365 mmOMR=MainMultiOMR() | |
366 d="C:\\Users\\victor\\Desktop\\cach" | |
367 mmOMR.runLoopBigData(d) | |
368 ''' | |
369 batchOMR=BatchOMR() | |
370 ff=FilesFunctions() | |
371 for outWalk in os.walk(rootDir): | |
372 dirName=outWalk[0] | |
373 subdirList=outWalk[1] | |
374 if "OMRS" in subdirList: | |
375 rootScore=dirName | |
376 omrFinished=True | |
377 scoreFinished=True | |
378 for outWalk2 in os.walk(rootScore): | |
379 dirName2=outWalk2[0] | |
380 files= ff.getAllImgFiles(dirName2) | |
381 omrs=ff.getAllXMLFiles(dirName2) | |
382 if len(files)>0 and len(omrs)<4: | |
383 omrFinished=False | |
384 | |
385 if os.path.exists(rootScore+"\\Process"): | |
386 movements=ff.SubDirPath(rootScore+"\\Process") | |
387 for movement in movements: | |
388 if not os.path.isfile(movement+"\\finalScore.xml"): | |
389 scoreFinished=False | |
390 else: | |
391 scoreFinished=False | |
392 | |
393 | |
394 if omrFinished==True and scoreFinished==False: | |
395 print "---- CONFIGURE SCORES ---" | |
396 batchOMR.setupApp(rootScore) | |
397 print "---- CONFIGURE GROUND ---" | |
398 batchOMR.setGround(rootScore) | |
399 if adaptOMRs: | |
400 print "---- ADAPT OMRs ---" | |
401 self.runAdaptAllOMRs(rootScore+"\\Process") | |
402 print "---- RUN BIG DATA ---" | |
403 self.runBigData(rootScore) | |
404 print "Waiting for processing..." | |
405 time.sleep(5) | |
406 self.runLoopBigData(rootDir,adaptOMRs) | |
407 | |
408 | |
409 ################################################################ | |
410 # @param rootDir root folder where all the scores to process are | |
411 def runBigDataGround(self,rootDir): | |
412 ''' | |
413 Checks if there is any folder to process to get the result | |
414 If "resultGeneral.xlsx" is not written and "finalScore.xml" and "ground.xml" are in the movement root dir, | |
415 launches the process | |
416 | |
417 usage | |
418 | |
419 mmOMR=MainMultiOMR() | |
420 d="C:\\Users\\victor\\Desktop\\data" | |
421 mmOMR.runBigDataGround(d) | |
422 ''' | |
423 ff=FilesFunctions() | |
424 for outWalk in os.walk(rootDir): | |
425 dirName=outWalk[0] | |
426 arrDir=dirName.split("\\") | |
427 if arrDir[-1]=="Process": | |
428 movements=ff.SubDirPath(dirName) | |
429 for movement in movements: | |
430 if not os.path.isfile(movement+"\\parts\\resultGeneral.xlsx"): | |
431 if os.path.isfile(movement+"\\finalScore.xml") and os.path.isfile(movement+"\\ground.xml") : | |
432 self.processMovementGround(movement) | |
433 | |
434 ################################################################ | |
435 # @param rootDir root folder where all the scores to process are | |
436 def runFinalXLS(self,rootDir): | |
437 ''' | |
438 Checks if there is any folder to process to get the result | |
439 If "resultGeneral.xlsx" is not written and "finalScore.xml" and "ground.xml" are in the movement root dir, | |
440 launches the process | |
441 | |
442 usage | |
443 | |
444 mmOMR=MainMultiOMR() | |
445 d="C:\\Users\\victor\\Desktop\\data" | |
446 mmOMR.runBigDataGround(d) | |
447 ''' | |
448 ed=ExcellData() | |
449 files=0 | |
450 S2_sum=0 | |
451 CP_sum=0 | |
452 PS_sum=0 | |
453 SE_sum=0 | |
454 SS_sum=0 | |
455 ff=FilesFunctions() | |
456 for outWalk in os.walk(rootDir): | |
457 dirName=outWalk[0] | |
458 arrDir=dirName.split("\\") | |
459 if arrDir[-1]=="Process": | |
460 movements=ff.SubDirPath(dirName) | |
461 for movement in movements: | |
462 if os.path.isfile(movement+"\\parts\\resultGeneral.xlsx"): | |
463 files=files+1 | |
464 s2,cp,ps,se,ss=ed.processResultGeneral(movement+"\\parts\\resultGeneral.xlsx") | |
465 S2_sum=S2_sum+s2 | |
466 CP_sum=CP_sum+cp | |
467 PS_sum=PS_sum+ps | |
468 SE_sum=SE_sum+se | |
469 SS_sum=SS_sum+ss | |
470 ed.writeFinalXLS(rootDir,S2_sum/files,CP_sum/files,PS_sum/files,SE_sum/files,SS_sum/files) | |
471 | |
472 ################################################################ | |
473 # @param rootDir root folder where all the scores to process are | |
474 def runLoopBigDataGround(self,rootDir): | |
475 ''' | |
476 Infinity loop for getting the results | |
477 | |
478 If "resultGeneral.xlsx" is not written and "finalScore.xml" and "ground.xml" are in the movement root dir, | |
479 launches the process | |
480 | |
481 usage | |
482 | |
483 mmOMR=MainMultiOMR() | |
484 d="C:\\Users\\victor\\Desktop\\data" | |
485 mmOMR.runLoopBigDataGround(d) | |
486 ''' | |
487 self.runBigDataGround(rootDir) | |
488 print "Waiting for results..." | |
489 time.sleep(5) | |
490 self.runLoopBigDataGround(rootDir) | |
491 | |
492 | |
493 ################################################################ | |
494 # @param dirGeneral root folder of the movement | |
495 | |
496 def __joinErrorParts(self,dirGeneral): | |
497 ''' | |
498 Joins the different result.S2.xml error in a single file. | |
499 The output file is "fullScore_errors.xml" | |
500 | |
501 The function tries to find the file "parts\\[idMovement]\\Result\\result.S2.xml" in each part | |
502 ''' | |
503 ff=FilesFunctions() | |
504 subdirname=ff.SubDirPath(dirGeneral+"\\parts\\") | |
505 fullScore=stream.Score() | |
506 for dirname in subdirname: | |
507 d=dirname+"\\Result\\" | |
508 urlSplit=dirname.split("\\") | |
509 part=int(urlSplit[-1]) | |
510 f=d+"\\result.S2.xml" | |
511 omr=converter.parse(f, forceSource=True) | |
512 part=omr.getElementsByClass(stream.Part)[0] | |
513 fullScore.append(part) | |
514 fullScore.write("musicxml", dirGeneral+"\\parts\\fullScore_errors.xml") | |
515 | |
516 | |
517 ############################################### | |
518 # @param rootDir root folder of the general data | |
519 def runCompleteProcess(self,rootDir): | |
520 ''' | |
521 Instead of working in parallel, this function launches a serial process with the different | |
522 steps involved | |
523 1.- SIKULI AUTOMATISM | |
524 2.- SETUP APPLICATION (copying files) | |
525 3.- CONVERT GROUND (taking the .krn and convert to ground.xml) | |
526 4.- RUN MULTIOMR BIG DATA | |
527 5.- RUN GET RESULT BIG DATA | |
528 | |
529 | |
530 usage: | |
531 mmOMR=MainMultiOMR() | |
532 d="C:\\Users\\victor\\Desktop\\data" | |
533 mmOMR.runCompleteProcess(d) | |
534 ''' | |
535 batchOMR=BatchOMR() | |
536 logging.basicConfig(filename=rootDir+'\\BigDataLogs.log',format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') | |
537 print "-------SIKULI AUTOMATISM----------" | |
538 logging.warning("---SIKULI AUTOMATISM--- "+rootDir) | |
539 batchOMR.processAllTiffFiles(rootDir,"ALL") | |
540 print "-------SETUP APPLICATION----------" | |
541 logging.warning("---SETUP APPLICATION--- "+rootDir) | |
542 batchOMR.setupApp(rootDir) | |
543 print "-------CONVERT GROUND----------" | |
544 logging.warning("---CONVERT GROUND--- "+rootDir) | |
545 batchOMR.setGround(rootDir) | |
546 logging.warning("------RUN MULTIOMR BIG DATA--- "+rootDir) | |
547 print "-------RUN MULTIOMR BIG DATA----------" | |
548 self.runBigData(rootDir) | |
549 print "-------RUN GET RESULT BIG DATA----------" | |
550 self.runBigDataGround(rootDir) | |
551 | |
552 ############################################### | |
553 # @param filename file to convert | |
554 def runConvertKrnToMusicXML(self,filename): | |
555 ''' | |
556 converts a .krn file to .xml using music21 | |
557 | |
558 usage: | |
559 mmOMR=MainMultiOMR() | |
560 file="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2\\k458.krn" | |
561 mmOMR.runConvertKrnToMusicXML(file) | |
562 ''' | |
563 omr=converter.parse(filename) | |
564 omr.write("musicxml", filename+'.xml') | |
565 | |
566 ############################################### | |
567 # @param filename file to convert | |
568 def runConvertMidiToMusicXML(self,filename): | |
569 ''' | |
570 converts a .mid file to .xml using music21 | |
571 | |
572 usage: | |
573 mmOMR=MainMultiOMR() | |
574 file="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2\\k458.mid" | |
575 mmOMR.runConvertKrnToMusicXML(file) | |
576 ''' | |
577 omr=converter.parse(filename) | |
578 #Reordering the different staffs | |
579 omrOrdered=stream.Score() | |
580 numberParts=len(omr.parts) | |
581 for i in reversed(range(numberParts)): | |
582 mypart=omr.parts[i] | |
583 | |
584 omrOrdered.insert(0,mypart) | |
585 omrOrdered.write("musicxml", filename+'.xml') | |
586 | |
587 ############################################### | |
588 # @param filename file to convert | |
589 def runConvertVoicesToChord(self,filename): | |
590 ''' | |
591 | |
592 ''' | |
593 mf=MeasureFunctions() | |
594 omr=converter.parse(filename) | |
595 omr=mf.convertVoicesToChord(omr) | |
596 omr.show() | |
597 | |
598 ############################################### | |
599 # @param filename file to convert | |
600 def runConvertBeamsToTriplets(self,filename): | |
601 ''' | |
602 | |
603 ''' | |
604 mf=MeasureFunctions() | |
605 omr=converter.parse(filename) | |
606 omr=mf.convertBeamsToTriplets(omr) | |
607 # omr.show() | |
608 omr.write("musicxml", filename+'.xml') | |
609 | |
610 def runRemovesEmptyVoices(self,filename): | |
611 ''' | |
612 | |
613 ''' | |
614 mf=MeasureFunctions() | |
615 omr=converter.parse(filename) | |
616 omr=mf.removesEmptyVoices(omr) | |
617 omr.write("musicxml", filename+'.xml') | |
618 | |
619 def runRemovesGaps(self,filename): | |
620 ''' | |
621 | |
622 ''' | |
623 mf=MeasureFunctions() | |
624 omr=converter.parse(filename) | |
625 omr=mf.removesGaps(omr) | |
626 omr.write("musicxml", filename+'.xml') | |
627 | |
628 | |
629 def runAdaptOMRs(self,dirname): | |
630 ''' | |
631 Runs the following process in one directory. | |
632 1.-Removing GAPS | |
633 2.-Converting voices to chords | |
634 3.-Converting triplets | |
635 4.-Removing Rest Voices | |
636 ''' | |
637 ff=FilesFunctions() | |
638 mf=MeasureFunctions() | |
639 files=ff.getFiles(dirname) | |
640 for f in files: | |
641 try: | |
642 print f | |
643 omr=converter.parse(f) | |
644 print "--- Removing GAPS---" | |
645 omr=mf.removesGaps(omr) | |
646 | |
647 print "--- Converting voices to chords---" | |
648 omr=mf.convertVoicesToChord( omr) | |
649 | |
650 print "--- Converting triplets---" | |
651 omr=mf.convertBeamsToTriplets(omr) | |
652 print "--- Removing Rest Voices---" | |
653 omr=mf.removeRestVoice(omr) | |
654 | |
655 omr.write("musicxml", f) | |
656 except: | |
657 pass | |
658 | |
659 def runAdaptAllOMRs(self,rootDir): | |
660 ''' | |
661 Adapt all the files in one directory tree | |
662 ''' | |
663 for outWalk in os.walk(rootDir): | |
664 dirName=outWalk[0] | |
665 self.runAdaptOMRs(dirName) | |
666 | |
667 | |
668 | |
669 | |
670 | |
671 ################################################## | |
672 # @param dirname the directory where the files are | |
673 def runViewM21(self,dirname): | |
674 ''' | |
675 Shows all the .xml files in a folder using music21 | |
676 to check the differences before and after processing | |
677 | |
678 usage: | |
679 mmOMR=MainMultiOMR() | |
680 dirname="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2" | |
681 mmOMR.runViewM21(dirname) | |
682 ''' | |
683 ff=FilesFunctions() | |
684 mf=MeasureFunctions() | |
685 files=ff.getFiles(dirname) | |
686 for f in files: | |
687 omr=converter.parse(f) | |
688 omr.show() | |
689 omr.show('text') | |
690 | |
691 | |
692 ################################################## | |
693 # @param dirname the directory where the files are | |
694 def runViewWrongMeasures(self,dirname): | |
695 ''' | |
696 Flags and prints the possible wrong measures | |
697 | |
698 usage: | |
699 mmOMR=MainMultiOMR() | |
700 dirname="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2" | |
701 mmOMR.runViewWrongMeasures(dirname) | |
702 ''' | |
703 ff=FilesFunctions() | |
704 mf=MeasureFunctions() | |
705 path = dirname | |
706 print("Path:"+path) | |
707 omr_files=ff.getAllFiles(path) | |
708 for f in omr_files: | |
709 omr=converter.parse(f) | |
710 arrayErrors=mf.flagIncorrectMeasures(omr)[1] | |
711 for array in arrayErrors: | |
712 for i in range(len(array)): | |
713 array[i]=array[i]+1 | |
714 print | |
715 print f | |
716 print "Errors measures duration:"+str(arrayErrors[0]) | |
717 print "Errors measures estimated:"+str(arrayErrors[1]) | |
718 print "Errors based on beams:"+str(arrayErrors[2]) | |
719 print "Errors based on last notes:"+str(arrayErrors[3]) | |
720 | |
721 | |
722 | |
723 | |
724 | |
725 | |
726 | |
727 |