Mercurial > hg > multiomr
changeset 2:46fb79167a61 tip
Main Code
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Automatism/BatchOMR.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,230 @@ +''' +Created on 10/11/2014 + +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +Functions related to SIKULI automatism +''' +import logging +import os +import sys +from subprocess import Popen +import shutil +from music21 import converter +from Functions import FilesFunctions + + + +class BatchOMR: + ''' + Class for the SIKULI process + ''' + ################################################## + # @param idOMR It can be "SE" "SS" "CP" "PS" "ALL" + # @param dirName folder where the images are and .xml will be + # @param files array with tiff files + def Batch(self,idOMR,dirName,files): + ''' + Runs the SIKULI process. + - idOMR: SE, SS, CP, PS + - if exists, skip + - it takes all the .tif files and convert them to SE.xml, SS.xml, CP.xml or PS.xml + - it waits until the process is finished + + usage: + ff=FilesFunctions() + dirName="C:\\Users\\victor\\Desktop\\data" + files= ff.getAllImgFiles(dirName) + batchOMR=BatchOMR() + batchOMR.Batch("PS",dirName,files) + ''' + + print "Processing...",dirName+"/"+idOMR+".xml" + if os.path.exists(dirName+"/"+idOMR+".xml"): + print "....Completed ",dirName+"/"+idOMR+".xml" + return + rootApp=os.path.dirname(sys.argv[0]) + rootApp=rootApp.replace("\\","/") + print rootApp + strFiles="" + for f in files: + strFiles=strFiles+" \""+f+"\"" + print dirName,strFiles + + dirName=dirName.replace("\\","/") + dirName="\""+dirName+"/\"" + + cwd=rootApp+"/sikuli1.0.1/runScript.cmd -r "+rootApp+"/sikuli/"+idOMR+".sikuli --args " + cwd=cwd+dirName+strFiles + print cwd + p = Popen(cwd) + p.wait() + p.communicate() + print "....Completed ",dirName+"/"+idOMR+".xml" + + + ############################################### + # @param rootDir root process folder + def cleanXMLFiles(self,rootDir): + ''' + Removes all the .xml files and .mro files in the tree folder + It is used for testing mainly + + usage: + + batchOMR=BatchOMR() + batchOMR.cleanXMLFiles("C:\\Users\\victor\\Desktop\\data") + ''' + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + fileList=outWalk[2] + for myfile in fileList: + if myfile.endswith('.xml'): + os.remove(dirName+"/"+myfile) + print myfile + if myfile.endswith('.mro'): + os.remove(dirName+"/"+myfile) + print myfile + + + ############################################### + # @param rootDir root process folder + # @param idOMR can be "PS" "CP" "SE" "SS" "ALL" + def processAllTiffFiles(self,rootDir,idOMR): + ''' + Runs the complete process for the tree folder + idOMR can be: + PS + CP + SE + SS + ALL (run all the OMRs). Capella is removed for many problems associated + + usage: + + batchOMR=BatchOMR() + batchOMR.processAllTiffFiles("C:\\Users\\victor\\Desktop\\data","SE") + ''' + print rootDir + logging.basicConfig(filename=rootDir+'\\BigDataLogs.log',format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + print('Found directory: %s' % dirName) + ff=FilesFunctions() + files= ff.getAllImgFiles(dirName) + if len(files)>0: + logging.warning(idOMR+" "+dirName) + if idOMR=="PS": + self.Batch("PS",dirName,files) + if idOMR=="SE": + self.Batch("SE",dirName,files) + if idOMR=="SS": + self.Batch("SS",dirName,files) + if idOMR=="CP": + self.Batch("CP",dirName,files) + if idOMR=="ALL": + # logging.warning("CP: "+dirName) + # Batch("CP",dirName,files) + logging.warning("PS: "+dirName) + self.Batch("PS",dirName,files) + logging.warning("SE: "+dirName) + self.Batch("SE",dirName,files) + logging.warning("SS: "+dirName) + self.Batch("SS",dirName,files) + + + ############################################### + # @param rootDir root process folder + def setupApp(self,rootDir): + ''' + Configures the main folder to process the data + Creates the "Process" close to "OMRS" folder and copy the .xml files. + - the parts files in "part/XML" folder with the structure: + - idpart.version.omrId.xml + - the full scores in fullScore/XML" folder with the structure: + - FS.version.omrId.xml + usage: + batchOMR=BatchOMR() + batchOMR.setupApp("C:\\Users\\victor\\Desktop\\data") + ''' + ff=FilesFunctions() + ################ + # FOR PARTS #### + ################ + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + subdirList=outWalk[1] + if "OMRS" in subdirList: + rootScore=dirName + if(dirName.upper().find("\\OMRS\\")!=-1 and dirName.upper().find("\\XML")!=-1 and dirName.upper().find("\\PARTS")!=-1): + arrDir=dirName.split("\\") + idpart=arrDir[len(arrDir)-2] + version=arrDir[len(arrDir)-3] + idmovement=arrDir[len(arrDir)-5] + files= ff.getAllXMLFiles(dirName) + myfolder=rootScore+"\\Process\\"+idmovement+"\\parts\\"+idpart+"\\XML\\" + if not os.path.exists(myfolder): + os.makedirs(myfolder) + for f in files: + if not os.path.isfile(myfolder+idpart+"."+version+"."+f): + shutil.copy2(dirName+"\\"+f, myfolder+idpart+"."+version+"."+f) + + ########################### + # FOR FULL SCORE ########## + ########################### + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + subdirList=outWalk[1] + if "OMRS" in subdirList: + rootScore=dirName + if(dirName.upper().find("\\OMRS\\")!=-1 and dirName.upper().find("\\XML")!=-1 and dirName.upper().find("\\FULLSCORE")!=-1): + arrDir=dirName.split("\\") + version=arrDir[len(arrDir)-2] + idmovement=arrDir[len(arrDir)-4] + files= ff.getAllXMLFiles(dirName) + myfolder=rootScore+"\\Process\\"+idmovement+"\\fullScore\\XML\\" + for f in files: + if not os.path.exists(myfolder): + os.makedirs(myfolder) + if not os.path.isfile(myfolder+"FS."+version+"."+f): + shutil.copy2(dirName+"\\"+f, myfolder+"FS."+version+"."+f) + + + + + + #################################### + # @param rootDir root process folder + def setGround(self,rootDir): + ''' + Process kern files in the OMRS folder (.krn) and set them as a "ground.xml" + in "Process" folder + + usage: + batchOMR=BatchOMR() + batchOMR.setGround("C:\\Users\\victor\\Desktop\\data") + ''' + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + ff=FilesFunctions() + kernFile=ff.getKernFile(dirName) + newpath=dirName.replace("\\OMRS\\","\\Process\\") + + if not os.path.isfile(newpath+'\\ground.xml'): + if kernFile!=None: + + print dirName+"\\"+kernFile + xmlFile=ff.getXMLFile(dirName) + + #if we have a .xml file, we copy it + if xmlFile!=None: + shutil.copyfile(dirName+"\\"+xmlFile,newpath+"\\ground.xml") + else: + omr=converter.parse(dirName+"\\"+kernFile) + omr.write("musicxml", newpath+'\\ground.xml') +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Automatism/__init__.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,1 @@ +from BatchOMR import BatchOMR
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MainMultiOMR.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,727 @@ +''' +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +The application can be run through command line (without windows interface) using +MainMultiOMR library + +''' +import logging +import time +import os +import gc +import sys +from subprocess import Popen +from music21 import stream +from music21 import converter +from Process import PipelineAlignment +from Process import Voting +from Process import SymbolConversion +from Process import FullScoreAlignment +from Automatism import BatchOMR +from Result import ProcessGroundS2 +from Result import ExcellData +from Functions import FilesFunctions +from Functions import MeasureFunctions +from Alignment import NWunsch +import shutil + +from Preprocessing import ossia +from Preprocessing import movements +from Preprocessing import preomr +import PythonMagick +import PyPDF2 + +class MainMultiOMR: + ''' + main functions to run the Big Data Process. + They can be called without interface, from another program, for example + .... + # instance + mmOMR=MainMultiOMR() + + # run the Big Data process once + mmOMR.runBigData("C:\\Users\\victor\\Desktop\\data") + + # run the Big Data waiting for changes + mmOMR.runDummyBigData("C:\\Users\\victor\\Desktop\\data") + + # run the Big Data Ground process once to get the results + mmOMR.runBigDataGroung("C:\\Users\\victor\\Desktop\\data") + + # run the Big Data Ground waiting for changes + mmOMR.runDummyBigData("C:\\Users\\victor\\Desktop\\data") + ''' + + def _loadNWunsch(self): + ''' + Load Needlemann-Wunsch algorith library by default + ''' + a=["foo00"] + b=["foo000"] + NWunsch.NWunsch_getSimilarity(a,b) + #print "Default NWunsch......" + + + def processPDF2TIFF(self,filename): + pdf_im = PyPDF2.PdfFileReader(file(filename, "rb")) + npage = pdf_im.getNumPages() + print('Converting %d pages.' % npage) + intMovement=0 + for p in range(npage): + im = PythonMagick.Image() + im.density('300') + print filename + im.read(str(filename)+'[' + str(p) +']') + strOut=str(filename) + str(p) + im.write(strOut+ '.tif') + + infile=strOut+ '.tif' + po = preomr.PreOMR(infile) + rv = po.split_movements(strOut+'_A.tif', strOut+'_B.tif') + if rv != None: + print("new movement was detected at system %d" % (rv,)) + + arrFile=filename.split("\\") + myFile=arrFile.pop() + path='\\'.join(arrFile) + print "**********************",path + if rv==0: + intMovement+=1 + dirMovement=path+"\\m"+str(intMovement) + os.makedirs(dirMovement) + shutil.copy(strOut+ '.tif', dirMovement+"\\page_"+str(p)+".tif") + else: + dirMovement=path+"\\m"+str(intMovement) + shutil.copy(strOut+ '_A.tif', dirMovement+"\\page_"+str(p)+".tif") + intMovement+=1 + dirMovement=path+"\\m"+str(intMovement) + os.makedirs(dirMovement) + shutil.copy(strOut+ '_B.tif', dirMovement+"\\page_"+str(p)+".tif") + + else: + shutil.copy(strOut+ '.tif', dirMovement+"\\page_"+str(p)+".tif") + + + + + def processOssia(self,rootDir): + ############################################### + # @param dirGeneral root movement folder + for dirname, dirnames, filenames in os.walk(rootDir): + for f in filenames: + fname_path = os.path.join(dirname, f) + if f.endswith(".tif"): + print fname_path + + ossia.process(fname_path, dirname+"\\_"+f) +# rootApp=os.path.dirname(sys.argv[0]) +# rootApp=rootApp.replace("\\","/") +# cwd="python.exe "+rootApp+"/Preprocessing/ossia.py "+fname_path+" "+fname_path +# +# print cwd +# p = Popen(cwd) +# p.wait() +# p.communicate() +# + + + def processMovement(self,dirGeneral): + ''' + Process just one movement. The structure should be + .... + \\movementName\\fullScore\\XML\\(the .xml files) + \\parts\\0\\ + \\1\\ + \\2\\XML\\(the .xml files) + + the result is \\movementName\\finalScore.xml + + usage: + mmOMR=MainMultiOMR() + mmOMR.processMovement("C:\Users\victor\Desktop\data\k458\Process\m2") + ''' + + + ff=FilesFunctions() + subdirnameParts=ff.SubDirPath(dirGeneral+"\\Parts\\") + fsOMRs_files=ff.getFiles(dirGeneral+"\\fullScore\\XML\\") + for dirname in subdirnameParts: + d=dirname+"/XML/" + urlSplit=dirname.split("\\") + part=int(urlSplit[-1]) + partOMRs_files=ff.getFiles(d) + print "---------S2------------" + logging.warning("Part:"+str(part)+" "+d) + self.setResultS2(d,part,fsOMRs_files,partOMRs_files) + + print "---------Synchronising scores and parts------------" + logging.warning("---------Synchronising scores and parts------------:"+dirGeneral) + #fsOMRs=ff.getOMRs(dirGeneral+"\\fullScore\\XML\\") + self.__runSynchroScoresAndParts(dirGeneral,fsOMRs_files) + + ############################################### + # @param path folder where the .xml files are + # @param idPart part number + # @param fsOMRs array with the full score files processed by music21 + # @param partOMRs array with the part files processed by music21 + def setResultS2(self,path,idPart,fsOMRs,partOMRs): + ''' + Takes the fullScores (processing the idPart) and parts. + It writes the result (result.S2.xml) in the dirname + + This function process each part independently + + usage: + + mmOMR=MainMultiOMR() + ff=FilesFunctions() + fsOMRs=ff.getOMRs("C:\\Users\\victor\\Desktop\\data\\k458_test\\Process\\m2\\fullScore\\XML") + partOMRs=ff.getOMRs("C:\\Users\\victor\\Desktop\\data\\k458_test\\Process\\m2\\parts\\0\\XML") + d="C:\\Users\\victor\\Desktop\\data\\k458_test\\Process\\m2\\parts\\0\\XML" + mmOMR.setResultS2(d,0,fsOMRs,partOMRs) + ''' + + + + pa=PipelineAlignment() + vote=Voting() + sc=SymbolConversion() + ff=FilesFunctions() + omr_symbolsAlign,betterOmrIds=pa.alignNJ_files(idPart,fsOMRs,partOMRs) + #The .txt with the OMRs involved (tree) + ff.writeText(path,betterOmrIds) + #voting + + outVote=vote.vote(omr_symbolsAlign) + #apply voices if it is needed + + outVote=sc.setVoices(outVote) + #convert to music21 + resultS2=sc.convertM21(outVote) + mf=MeasureFunctions() + #remove blank measures due to the alignment + resultS2_clean=mf.filterExtraMeasures(resultS2) + resultS2_clean.write("musicxml", path+'/result.S2.xml') + + + ############################################### + # @param dirGeneral folder where is the root of the movement + # @param fsOMRs array with the full score files processed by music21 + def __runSynchroScoresAndParts(self,dirGeneral,fsOMRs_files): + ''' + Takes the fullScores and part files generated to align the final full score + - dirGeneral is the movement URL + - fsOMRs is an array with the full scores OMRs processed by music21 + ''' + ff=FilesFunctions() + subdirnameParts=ff.SubDirPath(dirGeneral+"\\parts\\") + partsNumber=len(subdirnameParts) + fsa=FullScoreAlignment() + idCompleteScoreBetter=fsa.getIdBetterOMRFullScore(fsOMRs_files,partsNumber) + betterFsOMR=ff.getOMR(fsOMRs_files[idCompleteScoreBetter]) + finalScore=fsa.runSynchronisingMeasuresNJ(subdirnameParts,betterFsOMR) + betterFsOMR=None + finalScore.write("musicxml", dirGeneral+'/finalScore.xml') + finalScore=None + gc.collect() + print "----" + + + + ############################################### + # @param dirGeneral root movement folder + def processMovementGround(self,dirGeneral): + ''' + Process the result. Just one movement. It takes each OMR file and compare against the ground. + The differences are written in .XML and .xls + + .... + \\movementName\\fullScore\\XML\\(the .xml files) + \\parts\\0\\ + \\1\\ + \\2\\XML\\(the .xml files) + + the file finalScore.xml should be in \\movementName\\finalScore.xml + the file ground.xml should be in \\movementName\\ground.xml + + The final result is written in + \\movementName\\parts\\resultGeneral.xlsx + \\fullScore_errors.xml + + usage: + mmOMR=MainMultiOMR() + mmOMR.processMovementGround("C:\Users\victor\Desktop\data\k458\Process\m2") + ''' + percentagesArray=[] + betterOMRIds=[] + ff=FilesFunctions() + subdirname=ff.SubDirPath(dirGeneral+"\\parts\\") + filesFull=ff.getFiles(dirGeneral+"\\fullScore\\XML\\") + + ground=ff.getGround(dirGeneral) + groundparsed=converter.parse(ground, forceSource=True) + finalScore=ff.getFinalScore(dirGeneral) + finalScoreparsed=converter.parse(finalScore, forceSource=True) + + + for dirname in subdirname: + d=dirname+"/XML/" + urlSplit=dirname.split("\\") + part=int(urlSplit[-1]) + filesPart=ff.getFiles(d) + files=filesPart+filesFull + + print files + pg=ProcessGroundS2() + ErrorsMatrix=[] + percentages=[] + + OMRs=[] + OMRs.append(groundparsed) + OMRs.append(finalScoreparsed) + + + + percentage,errors,scoreWithErrors= pg.getSimilarity(OMRs,part) + ErrorsMatrix.append(errors) + percentages.append(percentage) + if not os.path.exists(dirname+"\\Result"): + os.makedirs(dirname+"\\Result") + + scoreWithErrors.write("musicxml", dirname+"\\Result\\result.S2.xml") + + for i in range(len(files)): + try: + OMRs[1]=ff.getOMR(files[i]) + percentage,errors,scoreWithErrors= pg.getSimilarity(OMRs,part) + ErrorsMatrix.append(errors) + percentages.append(percentage) + scoreWithErrors.write("musicxml", dirname+"\\Result\\"+os.path.basename(files[i])) + except: + print "ERROR OMR READING" + ErrorsMatrix.append("ERROR OMR READING") + percentages.append(0) + + + f=open(d+"betterOMR.txt","r") + betterOMRId=f.readlines() + f.close() + betterOMRIds.append(betterOMRId) + print "betterOMRIds",betterOMRIds + ed=ExcellData() + files.insert(0,dirname+"\\Result\\result.S2.xml" ) + print files + ed.saveData(ErrorsMatrix,files,percentages) + percentagesArray.append(percentages) + + + ed=ExcellData() + ed.saveGlobalData(percentagesArray,dirGeneral,betterOMRIds,files) + self.__joinErrorParts(dirGeneral) + print "----------- END ------------" + + ################################################################ + # @param rootDir root folder where all the scores to process are + def runBigData(self,rootDir): + ''' + Checks if there is any folder to process + If the folder "Process" is written, but the "finalScore.xml" is not, + runs the procedure + + usage + + mmOMR=MainMultiOMR() + d="C:\\Users\\victor\\Desktop\\cach" + mmOMR.runBigData(d) + ''' + ff=FilesFunctions() + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + arrDir=dirName.split("\\") + if arrDir[-1]=="Process": + movements=ff.SubDirPath(dirName) + for movement in movements: + print movement + if not os.path.isfile(movement+"\\finalScore.xml"): + logging.warning("Movement:"+movement+" "+rootDir) + self.processMovement(movement) + + ################################################################ + # @param rootDir root folder where all the scores to process are + def runLoopBigData(self,rootDir,adaptOMRs=False): + ''' + Infinity loop for processing data + Checks if there is any folder to process + If the folder "Process" is written, but the "finalScore.xml" is not, + runs the procedure + + usage + + mmOMR=MainMultiOMR() + d="C:\\Users\\victor\\Desktop\\cach" + mmOMR.runLoopBigData(d) + ''' + batchOMR=BatchOMR() + ff=FilesFunctions() + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + subdirList=outWalk[1] + if "OMRS" in subdirList: + rootScore=dirName + omrFinished=True + scoreFinished=True + for outWalk2 in os.walk(rootScore): + dirName2=outWalk2[0] + files= ff.getAllImgFiles(dirName2) + omrs=ff.getAllXMLFiles(dirName2) + if len(files)>0 and len(omrs)<4: + omrFinished=False + + if os.path.exists(rootScore+"\\Process"): + movements=ff.SubDirPath(rootScore+"\\Process") + for movement in movements: + if not os.path.isfile(movement+"\\finalScore.xml"): + scoreFinished=False + else: + scoreFinished=False + + + if omrFinished==True and scoreFinished==False: + print "---- CONFIGURE SCORES ---" + batchOMR.setupApp(rootScore) + print "---- CONFIGURE GROUND ---" + batchOMR.setGround(rootScore) + if adaptOMRs: + print "---- ADAPT OMRs ---" + self.runAdaptAllOMRs(rootScore+"\\Process") + print "---- RUN BIG DATA ---" + self.runBigData(rootScore) + print "Waiting for processing..." + time.sleep(5) + self.runLoopBigData(rootDir,adaptOMRs) + + + ################################################################ + # @param rootDir root folder where all the scores to process are + def runBigDataGround(self,rootDir): + ''' + Checks if there is any folder to process to get the result + If "resultGeneral.xlsx" is not written and "finalScore.xml" and "ground.xml" are in the movement root dir, + launches the process + + usage + + mmOMR=MainMultiOMR() + d="C:\\Users\\victor\\Desktop\\data" + mmOMR.runBigDataGround(d) + ''' + ff=FilesFunctions() + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + arrDir=dirName.split("\\") + if arrDir[-1]=="Process": + movements=ff.SubDirPath(dirName) + for movement in movements: + if not os.path.isfile(movement+"\\parts\\resultGeneral.xlsx"): + if os.path.isfile(movement+"\\finalScore.xml") and os.path.isfile(movement+"\\ground.xml") : + self.processMovementGround(movement) + + ################################################################ + # @param rootDir root folder where all the scores to process are + def runFinalXLS(self,rootDir): + ''' + Checks if there is any folder to process to get the result + If "resultGeneral.xlsx" is not written and "finalScore.xml" and "ground.xml" are in the movement root dir, + launches the process + + usage + + mmOMR=MainMultiOMR() + d="C:\\Users\\victor\\Desktop\\data" + mmOMR.runBigDataGround(d) + ''' + ed=ExcellData() + files=0 + S2_sum=0 + CP_sum=0 + PS_sum=0 + SE_sum=0 + SS_sum=0 + ff=FilesFunctions() + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + arrDir=dirName.split("\\") + if arrDir[-1]=="Process": + movements=ff.SubDirPath(dirName) + for movement in movements: + if os.path.isfile(movement+"\\parts\\resultGeneral.xlsx"): + files=files+1 + s2,cp,ps,se,ss=ed.processResultGeneral(movement+"\\parts\\resultGeneral.xlsx") + S2_sum=S2_sum+s2 + CP_sum=CP_sum+cp + PS_sum=PS_sum+ps + SE_sum=SE_sum+se + SS_sum=SS_sum+ss + ed.writeFinalXLS(rootDir,S2_sum/files,CP_sum/files,PS_sum/files,SE_sum/files,SS_sum/files) + + ################################################################ + # @param rootDir root folder where all the scores to process are + def runLoopBigDataGround(self,rootDir): + ''' + Infinity loop for getting the results + + If "resultGeneral.xlsx" is not written and "finalScore.xml" and "ground.xml" are in the movement root dir, + launches the process + + usage + + mmOMR=MainMultiOMR() + d="C:\\Users\\victor\\Desktop\\data" + mmOMR.runLoopBigDataGround(d) + ''' + self.runBigDataGround(rootDir) + print "Waiting for results..." + time.sleep(5) + self.runLoopBigDataGround(rootDir) + + + ################################################################ + # @param dirGeneral root folder of the movement + + def __joinErrorParts(self,dirGeneral): + ''' + Joins the different result.S2.xml error in a single file. + The output file is "fullScore_errors.xml" + + The function tries to find the file "parts\\[idMovement]\\Result\\result.S2.xml" in each part + ''' + ff=FilesFunctions() + subdirname=ff.SubDirPath(dirGeneral+"\\parts\\") + fullScore=stream.Score() + for dirname in subdirname: + d=dirname+"\\Result\\" + urlSplit=dirname.split("\\") + part=int(urlSplit[-1]) + f=d+"\\result.S2.xml" + omr=converter.parse(f, forceSource=True) + part=omr.getElementsByClass(stream.Part)[0] + fullScore.append(part) + fullScore.write("musicxml", dirGeneral+"\\parts\\fullScore_errors.xml") + + + ############################################### + # @param rootDir root folder of the general data + def runCompleteProcess(self,rootDir): + ''' + Instead of working in parallel, this function launches a serial process with the different + steps involved + 1.- SIKULI AUTOMATISM + 2.- SETUP APPLICATION (copying files) + 3.- CONVERT GROUND (taking the .krn and convert to ground.xml) + 4.- RUN MULTIOMR BIG DATA + 5.- RUN GET RESULT BIG DATA + + + usage: + mmOMR=MainMultiOMR() + d="C:\\Users\\victor\\Desktop\\data" + mmOMR.runCompleteProcess(d) + ''' + batchOMR=BatchOMR() + logging.basicConfig(filename=rootDir+'\\BigDataLogs.log',format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') + print "-------SIKULI AUTOMATISM----------" + logging.warning("---SIKULI AUTOMATISM--- "+rootDir) + batchOMR.processAllTiffFiles(rootDir,"ALL") + print "-------SETUP APPLICATION----------" + logging.warning("---SETUP APPLICATION--- "+rootDir) + batchOMR.setupApp(rootDir) + print "-------CONVERT GROUND----------" + logging.warning("---CONVERT GROUND--- "+rootDir) + batchOMR.setGround(rootDir) + logging.warning("------RUN MULTIOMR BIG DATA--- "+rootDir) + print "-------RUN MULTIOMR BIG DATA----------" + self.runBigData(rootDir) + print "-------RUN GET RESULT BIG DATA----------" + self.runBigDataGround(rootDir) + + ############################################### + # @param filename file to convert + def runConvertKrnToMusicXML(self,filename): + ''' + converts a .krn file to .xml using music21 + + usage: + mmOMR=MainMultiOMR() + file="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2\\k458.krn" + mmOMR.runConvertKrnToMusicXML(file) + ''' + omr=converter.parse(filename) + omr.write("musicxml", filename+'.xml') + + ############################################### + # @param filename file to convert + def runConvertMidiToMusicXML(self,filename): + ''' + converts a .mid file to .xml using music21 + + usage: + mmOMR=MainMultiOMR() + file="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2\\k458.mid" + mmOMR.runConvertKrnToMusicXML(file) + ''' + omr=converter.parse(filename) + #Reordering the different staffs + omrOrdered=stream.Score() + numberParts=len(omr.parts) + for i in reversed(range(numberParts)): + mypart=omr.parts[i] + + omrOrdered.insert(0,mypart) + omrOrdered.write("musicxml", filename+'.xml') + + ############################################### + # @param filename file to convert + def runConvertVoicesToChord(self,filename): + ''' + + ''' + mf=MeasureFunctions() + omr=converter.parse(filename) + omr=mf.convertVoicesToChord(omr) + omr.show() + + ############################################### + # @param filename file to convert + def runConvertBeamsToTriplets(self,filename): + ''' + + ''' + mf=MeasureFunctions() + omr=converter.parse(filename) + omr=mf.convertBeamsToTriplets(omr) +# omr.show() + omr.write("musicxml", filename+'.xml') + + def runRemovesEmptyVoices(self,filename): + ''' + + ''' + mf=MeasureFunctions() + omr=converter.parse(filename) + omr=mf.removesEmptyVoices(omr) + omr.write("musicxml", filename+'.xml') + + def runRemovesGaps(self,filename): + ''' + + ''' + mf=MeasureFunctions() + omr=converter.parse(filename) + omr=mf.removesGaps(omr) + omr.write("musicxml", filename+'.xml') + + + def runAdaptOMRs(self,dirname): + ''' + Runs the following process in one directory. + 1.-Removing GAPS + 2.-Converting voices to chords + 3.-Converting triplets + 4.-Removing Rest Voices + ''' + ff=FilesFunctions() + mf=MeasureFunctions() + files=ff.getFiles(dirname) + for f in files: + try: + print f + omr=converter.parse(f) + print "--- Removing GAPS---" + omr=mf.removesGaps(omr) + + print "--- Converting voices to chords---" + omr=mf.convertVoicesToChord( omr) + + print "--- Converting triplets---" + omr=mf.convertBeamsToTriplets(omr) + print "--- Removing Rest Voices---" + omr=mf.removeRestVoice(omr) + + omr.write("musicxml", f) + except: + pass + + def runAdaptAllOMRs(self,rootDir): + ''' + Adapt all the files in one directory tree + ''' + for outWalk in os.walk(rootDir): + dirName=outWalk[0] + self.runAdaptOMRs(dirName) + + + + + + ################################################## + # @param dirname the directory where the files are + def runViewM21(self,dirname): + ''' + Shows all the .xml files in a folder using music21 + to check the differences before and after processing + + usage: + mmOMR=MainMultiOMR() + dirname="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2" + mmOMR.runViewM21(dirname) + ''' + ff=FilesFunctions() + mf=MeasureFunctions() + files=ff.getFiles(dirname) + for f in files: + omr=converter.parse(f) + omr.show() + omr.show('text') + + + ################################################## + # @param dirname the directory where the files are + def runViewWrongMeasures(self,dirname): + ''' + Flags and prints the possible wrong measures + + usage: + mmOMR=MainMultiOMR() + dirname="C:\\Users\\victor\\Desktop\\data\\k458\\OMRS\\m2" + mmOMR.runViewWrongMeasures(dirname) + ''' + ff=FilesFunctions() + mf=MeasureFunctions() + path = dirname + print("Path:"+path) + omr_files=ff.getAllFiles(path) + for f in omr_files: + omr=converter.parse(f) + arrayErrors=mf.flagIncorrectMeasures(omr)[1] + for array in arrayErrors: + for i in range(len(array)): + array[i]=array[i]+1 + print + print f + print "Errors measures duration:"+str(arrayErrors[0]) + print "Errors measures estimated:"+str(arrayErrors[1]) + print "Errors based on beams:"+str(arrayErrors[2]) + print "Errors based on last notes:"+str(arrayErrors[3]) + + + + + + + + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Preprocessing/movements.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,40 @@ +#!/home/alex/anaconda/bin/python +#!/home/alex/anaconda/bin/python + +import sys, getopt +import preomr + +def usage(): + print "Please provide input and output filenames." + +def main(argv): + if len(argv) < 3: + usage() + sys.exit(2) + infile = argv[0] + outfileA = argv[1] + outfileB = argv[2] + process(infile, outfileA, outfileB) + +def process(infile, outfileA, outfileB): + po = preomr.PreOMR(infile) + # TODO make deskewing an option + #po.deskew() + #po.staffline_removal() + rv = po.split_movements(outfileA, outfileB) + if rv != None: + print "new movement at position %d" % rv + sys.exit(0) + else: + print "no change of movement detected" + sys.exit(1) + +# Commandline parameter processing +# Make working folder +# Explode PDFs into PNGs? +# Deskew (optional) +# Find staves +# Print output image(s) + +if __name__ == "__main__": + main(sys.argv[1:]) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Preprocessing/ossia.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,33 @@ +#!/home/alex/anaconda/bin/python + +import sys, getopt +import preomr + +def usage(): + print "Please provide input and output filenames." + +def main(argv): + if len(argv) < 2: + usage() + sys.exit(2) + infile = argv[0] + outfile = argv[1] + + process(infile, outfile) + + +def process(infile, outfile): + po = preomr.PreOMR(infile) + #po.staffline_removal() + po.remove_ossia() + po.save(outfile) + +# Commandline parameter processing +# Make working folder +# Explode PDFs into PNGs? +# Deskew (optional) +# Find staves +# Print output image(s) + +if __name__ == "__main__": + main(sys.argv[1:]) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Preprocessing/preomr.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,663 @@ +import sys +import cv2 +import numpy as np +import math +import copy + +from gamera.core import * +from gamera.toolkits.musicstaves import musicstaves_rl_roach_tatem +from gamera.toolkits.musicstaves import musicstaves_rl_fujinaga +from gamera.toolkits.musicstaves import stafffinder_miyao +from gamera.toolkits.musicstaves import stafffinder_dalitz +from gamera.toolkits.musicstaves import stafffinder_projections +from gamera.plugins import numpy_io +init_gamera() + +#import ossiafinder_dalitz + +def intersect(r1,r2): + """Returns the intersection of two rectangles""" + x1 = max(r1['x'], r2['x']) + y1 = max(r1['y'], r2['y']) + x2 = min(r1['x'] + r1['width'], r2['x'] + r2['width']) + y2 = min(r1['y'] + r1['height'], r2['y'] + r2['height']) + result = {"x": x1, "y": y1, "width": x2 - x1, "height": y2-y1} + result['area'] = result['width'] * result['height'] + return(result) + +def ydist(r1,r2): + """distance on y-axis between two non-interecting rectangles""" + top1 = r1['y'] + bottom1 = r1['y'] + r1['height'] + + top2 = r2['y'] + bottom2 = r2['y'] + r2['height'] + return(min(abs(top1-bottom2), abs(top2-bottom1))) + + +def show(img, factor=0.5): + """ show an image until the escape key is pressed + :param factor: scale factor (default 0.5, half size) + """ + if factor != 1.0: + img = cv2.resize(img, (0,0), fx=factor, fy=factor) + + cv2.imwrite('show.png',img) +# while(1): +# k = cv2.waitKey(0) +# if k==27: # Esc key to quit +# cv2.destroyAllWindows() +# exit() +# if k==32: # Space to stop +# cv2.destroyAllWindows() +# break + + +def max_staff_height(blob): + result = 0 + for staff in blob['staves']: + top = staff[0].y_list[0] + bottom = staff[-1].y_list[0] + result = max(result, bottom-top) + return(result) + + +def deskew(img): + """Deskews the given image based on lines detected with opencv's + HoughLines function.""" + print "Deskewing." + imgHeight, imgWidth, imgDepth = img.shape + img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) + img_edges = cv2.Canny(img_gray,50,150,apertureSize = 3) + minLineLength = int(imgWidth*0.5) + houghThresh = int(imgWidth*0.15) + maxLineGap = 10 + #lines = cv2.HoughLinesP(img_edges,1,np.pi/(180*1),houghThresh,minLineLength,maxLineGap) + lines = cv2.HoughLines(img_edges,1,np.pi/(180*3),houghThresh) + + angles = [] + for rho,theta in lines[0]: + angles.append((theta - (np.pi / 2))) + + a = np.cos(theta) + b = np.sin(theta) + x0 = a*rho + y0 = b*rho + x1 = int(x0 + imgWidth*(-b)) + y1 = int(y0 + imgWidth*(a)) + x2 = int(x0 - imgWidth*(-b)) + y2 = int(y0 - imgWidth*(a)) + #cv2.line(img,(x1,y1),(x2,y2),(255,0,0),2) + + middle = np.median(angles) + middle_deg = middle * (180/np.pi) + + rotation = cv2.getRotationMatrix2D((imgWidth/2,imgHeight/2),middle_deg,1.0) + + # rotate while inverted. the background is filled with zeros + # (black), this inversion means that ends up white + deskewed = cv2.bitwise_not(cv2.warpAffine(cv2.bitwise_not(img), + rotation, + (imgWidth,imgHeight)) + ) + return(deskewed) + +class PreOMR(object): + stavelineWidthThresh = 0.5 + + def __init__(self, infile, deskew=False): + self.debug = True + self.infile = infile + self.img = cv2.imread(self.infile) + if deskew: + self.img = deskew(self.img) + self.original = self.img + self.imgHeight, self.imgWidth, self.imgDepth = self.img.shape + self.img_gray = cv2.cvtColor(self.img,cv2.COLOR_BGR2GRAY) + if self.debug: + self.debug_img = self.img.copy() + ret2,self.img_binary = cv2.threshold(self.img_gray, + 0,255,cv2. + THRESH_BINARY+cv2. + THRESH_OTSU) + + def staffline_removal(self): + gamera_img = numpy_io.from_numpy(self.img) + #self.save('tmp.png') + #gamera_img = load_image('tmp.png') + + #ms = musicstaves_rl_roach_tatem.MusicStaves_rl_roach_tatem(gamera_img) + ms = musicstaves_rl_fujinaga.MusicStaves_rl_fujinaga(gamera_img) + cv2.imwrite('tmp.png', self.img) + ms.remove_staves(crossing_symbols = 'bars') + ms.image.save_PNG("tmpb.png") + staffless = cv2.imread("tmp.png", cv2.CV_LOAD_IMAGE_GRAYSCALE) + return(staffless) + + def find_staves(self, img): + gamera_img = numpy_io.from_numpy(img) + #sf = stafffinder_projections.StaffFinder_projections(gamera_img) + #sf.find_staves(follow_wobble=True,preprocessing=0) + #sf = stafffinder_dalitz.StaffFinder_dalitz(gamera_img) + sf = stafffinder_miyao.StaffFinder_miyao(gamera_img) + sf.find_staves() + #sf.find_staves(debug=2) + + staves = sf.get_skeleton() +# if self.debug: +# for i, staff in enumerate(staves): +# print "Staff %d has %d staves:" % (i+1, len(staff)) +# for j, line in enumerate(staff): +# print(" %d. line at (%d,%d)" % (j+1,line.left_x,line.y_list[0])) + return(staves) + + def find_blobs(self, img_binary): + """Find blobs in the given image, returned as a list of associative + lists containing various cheap metrics for each blob.""" + + blobs = [] + img_inverted = cv2.bitwise_not(img_binary) + contours, hierarchy = cv2.findContours(img_inverted,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) + for (i, c) in enumerate(contours): + blob = {} + blobs.append(blob) + + blob['area'] = cv2.contourArea(c) + + m = cv2.moments(c) + if m['m00'] == 0: # When would this be true? + blob['x'] = 0 + blob['y'] = 0 + else: + blob['x'] = m['m10'] / m['m00'] + blob['y'] = m['m01'] / m['m00'] + + blob['contour'] = c + + rect = cv2.boundingRect(c) + blob['rect'] = {'x': rect[0], + 'y': rect[1], + 'width': rect[2], + 'height': rect[3] + } + blob['boundingRect'] = rect + blob['hull'] = hull = cv2.convexHull(c) + blob['hull_area'] = abs(cv2.contourArea(hull)) + blob['system'] = False + blob['parent'] = None + #blob['perimeter'] = perimeter = cv2.arcLength(c, True) + #blob['roundness'] = (perimeter * 0.282) / math.sqrt(area) + #(centre, axes, orientation) = cv2.fitEllipse(c) + #blob['orientation'] = orientation / 180 + #print "orientation: %f" % orientation + #blob['aspect'] = float(rect[1]) / float(rect[3]) + + return blobs + + def find_bars(self, system): + staffless = self.staffline_removal() + blobs = self.blobs + + """Finds the barlines in the system, given a binary image, a hash of + info about the system, and blobs detected in the image. + + """ + img = system['image'] + + for staff in system['staves']: + min_x = 0 + max_x = self.imgWidth + + for line in staff: + min_x = max(min_x, line.left_x) + max_x = min(max_x, line.left_x + len(line.y_list)) + + if self.debug: + for (i,y) in enumerate(line.y_list): + x = line.left_x + i + cv2.line(self.debug_img,(x,y),(x,y),(0,255,0),3) + +# cv2.line(img,(0,int(start)),(imgWidth,int(start)),(0,255,255),3) +# cv2.line(img,(0,int(stop)),(imgWidth,int(stop)),(0,255,255),3) +# cv2.line(img,(0,int(first_staveline)),(imgWidth,int(first_staveline)),(255,255,0),3) +# cv2.line(img,(0,int(last_staveline)),(imgWidth,int(last_staveline)),(255,255,0),3) + + # assuming single staff for now.. + barlines = [0] + system['barlines'] = barlines + + x_projection = [] + + for x in range(min_x, max_x): + first_staveline = staff[0].y_list[x - staff[0].left_x] + last_staveline = staff[-1].y_list[x - staff[-1].left_x] + + #print("Stavelines: first %d last %d" % (first_staveline, last_staveline)) + stave_height = last_staveline - first_staveline + + # mean distance between stavelines + avg_inter = float(stave_height) / float(len(staff)-1) + #print("avg_inter: %f" % (avg_inter,)) + + # where to look a bit above and below the stave for whitespace + # above a barline + gap = avg_inter / 2.0 + start = first_staveline - gap + stop = last_staveline + gap + + # above stave, stave and below stave + top = float(gap - + cv2.countNonZero(staffless[start:first_staveline, + x:x+1])) / float(gap) + mid = float(stave_height - + cv2.countNonZero(staffless[first_staveline:last_staveline, + x:x+1]) + ) / float(stave_height) + bot = float(gap - + cv2.countNonZero(staffless[last_staveline:stop, x:x+1]) + ) / float(gap) + x_projection.append((top,mid,bot)) + + barline_start = -1 + gap_dist = avg_inter/4 + gap_min = (avg_inter/float(stave_height)) * 0.3 + gap_tolerance = int(avg_inter/10) + + margin = int(avg_inter*2) + + for x in range(min_x+margin, max_x-margin): + (top,mid,bot) = x_projection[x - min_x] + #if self.debug: + #cv2.line(system['image'],(x,first_staveline),(x,int(first_staveline+((last_staveline-first_staveline)*mid))),(255,255,0),1) + + # found start of barline candidate + if top < 0.6 and bot < 0.6 and mid > 0.95: + if barline_start < 0: + barline_start = x + else: + if barline_start > 0: + # check there is nothing either side of 'barline' + barline_stop = x-1 + barline_mid = barline_stop - ((barline_stop - barline_start)/2) + #print("barline start %d stop %d mid %d" % (barline_start, barline_stop, barline_mid)) + left = int(max(0,barline_start-gap_dist)) + right = int(min(system['width']-1,(x-1)+gap_dist)) + + total = 0 + for i in range(left-gap_tolerance, left+gap_tolerance+1): + total = total + x_projection[i-min_x][1] + left_avg = total / ((gap_tolerance*2)+1) + + total = 0 + for i in range(right-gap_tolerance, right+gap_tolerance+1): + total = total + x_projection[i-min_x][1] + right_avg = total / ((gap_tolerance*2)+1) + + cv2.line(img,(left,first_staveline),(left,last_staveline),(255,0,255),1) + cv2.line(img,(right,first_staveline),(right,last_staveline),(255,0,255),1) + + if (left_avg <= gap_min and right_avg <= gap_min): + #print("success: left_avg %f right_avg %f" % (left_avg, right_avg)) + cv2.line(img,(barline_mid,first_staveline),(barline_mid,last_staveline),(255,0,0),3) + barlines.append(barline_mid) + else: + #print("fail: left_avg %f right_avg %f" % (left_avg, right_avg)) + cv2.line(img,(barline_mid,first_staveline),(barline_mid,last_staveline),(0,255,0),3) + #show(img) + barline_start = -1 + (x1, y1, x2, y2) = system['location'] + #show(system['image'][y1:y2, x1:x2]) + + def extract_bars(self, system, blobs): + """Given information about a system (including identified barlines), + and all the blobs on a page returns a list of bars in the system, + each an associative array containing image and location. + + """ + + img = system['image'] + + barlines = system['barlines'] + + result = [] + + for i in range(0,len(barlines)): + barstart = barlines[i] + if i == (len(barlines)-1): + barstop = system['width'] + else: + barstop = barlines[i+1] + #print("barstart %d barstop %d" % (barstart, barstop)) + contours = [system['contour']] + x1 = barstart + y1 = system['location'][1] + x2 = barstop + y2 = system['location'][3] + h = y2 - y1 + w = x2 - x1 + #print("height %d width %d" % (h, w)) + for blob in blobs: + if blob['parent'] == system: + if blob['rect']['x'] >= barstart and blob['rect']['x'] + blob['rect']['width'] <= barstop: + contours.append(blob['contour']) + + mask = np.zeros((self.imgHeight,self.imgWidth,1), np.uint8) + + cv2.drawContours(mask, contours, -1, 255, -1); + + inv = cv2.bitwise_not(img) + dest = cv2.bitwise_and(inv,inv,mask = mask) + dest = cv2.bitwise_not(dest) + img_bar = dest[y1:y2, x1:x2] + bar = {'image': img_bar, + 'page': dest, + 'location': [x1,y1,x2,y2] + } + result.append(bar) + #show(img_bar) + return(result) + + + + def find_staveblobs(self, cutstaves=False,img=None): + if img == None: + img = self.img + img_binary = self.img_binary + else: + img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) + ret2,img_binary = cv2.threshold(img_gray, + 0,255,cv2. + THRESH_BINARY+cv2. + THRESH_OTSU) + + staves = self.find_staves(img) + blobs = self.find_blobs(img_binary) + + staveblobs = [] + otherblobs = [] + + if self.debug: + for staff in staves: + for line in staff: + y = line.y_list[0] + cv2.line(self.debug_img,(0,y),(self.imgWidth,y),(0,255,0),3) + for blob in blobs: + rect = blob['rect'] + blob['staves'] = [] + blob['system'] = False + # large enough to contain a stave? + blob['large'] = False + if rect['width'] > (self.imgWidth * self.stavelineWidthThresh): + blob['large'] = True + if self.debug: + cv2.drawContours(self.debug_img,[blob['contour']],-1, (0, 255,255),2) + for staff in staves: + inside = True + for staveline in staff: + leftmost = staveline.y_list[0] + # all stafflines have to be in blob + if leftmost < rect['y'] or leftmost > (rect['y'] + rect['height']): + inside = False + break + if inside: + blob['system'] = True + blob['staves'].append(staff) + if blob['system']: + staveblobs.append(blob) + print("found system with %d staves" % len(blob['staves'])) + if self.debug: + cv2.drawContours(self.debug_img,[blob['contour']],-1, (0, 0,255), 2) + else: + otherblobs.append(blob) + + return(staveblobs, otherblobs) + + def find_systems(self): + img = self.img_binary + #print "finding staves" + (staveblobs, otherblobs) = self.find_staveblobs() + #print("found %d staves" % (len(staveblobs),)) + blobs = staveblobs + otherblobs + self.blobs = blobs + # systems = [] + systems = staveblobs + + # attach disconnected bits in bounding box + tidied = 0 + for blob in blobs: + if not blob['system']: + blob['parent'] = None + for system in systems: + rect = intersect(system['rect'], blob['rect']) + if (rect['height'] > 0 and rect['width'] > 0): + # Biggest intersection wins + if (blob['parent'] == None) or (rect['area'] > blob['intersection']['area']): + blob['parent'] = system + blob['intersection'] = rect + + # Just assign to closest bounding rectangle on y-axis + if blob['parent'] == None: + mindist = None + for system in systems: + dist = ydist(system['rect'], blob['rect']) + if mindist == None or mindist > dist: + blob['parent'] = system + mindist = dist + if blob['parent'] == None: + print "wtf" + else: + tidied = tidied + 1 + #print "tidied %d" % tidied + + # create new image for systems + for system in systems: + contours = [system['contour']] + x1 = system['rect']['x'] + y1 = system['rect']['y'] + x2 = system['rect']['x'] + system['rect']['width'] + y2 = system['rect']['y'] + system['rect']['height'] + + children = 0 + for blob in blobs: + if blob['parent'] == system: + children = children + 1 + contours.append(blob['contour']) + # include blob in image size/location + x1 = min(x1, blob['rect']['x']) + y1 = min(y1, blob['rect']['y']) + x2 = max(x2, blob['rect']['x'] + blob['rect']['width']) + y2 = max(y2, blob['rect']['y'] + blob['rect']['height']) + + #print("found %d children" % children) + + mask = np.zeros((self.imgHeight,self.imgWidth,1), np.uint8) + + cv2.drawContours(mask, contours, -1, 255, -1); + #src = img[x1:y1, x2:y2] + #srcMask = mask[y1:y2, x1:x2] + kernel = np.ones((4,4),np.uint8) + mask=cv2.dilate(mask,kernel,iterations=3) + + inv = cv2.bitwise_not(self.img) + dest = cv2.bitwise_and(inv,inv,mask = mask) + dest = cv2.bitwise_not(dest) + + (h,w,d) = dest.shape + system['image'] = dest + system['location'] = (x1, y1, x2, y2) + system['height'] = h + system['width'] = w + + min_x = self.imgWidth + + for staff in system['staves']: + for line in staff: + min_x = min(min_x, line.left_x) + + system['stave_min_x'] = min_x + + #self.find_bars(system) + #system['bar_images'] = self.extract_bars(system, blobs) + if self.debug: + cv2.imwrite('debug.png', self.debug_img) + return(systems,blobs) + + def blob_image(self,img,blob): + r = blob['rect'] + y1 = r['y'] + x1 = r['x'] + y2 = r['y'] + r['height'] + x2 = r['x'] + r['width'] + return(img[y1:y2, x1:x2]) + +# def join_broken_staves(self): +# img = self.img +# (staveblobs, otherblobs) = self.find_staveblobs() +# for i in range(0, len(staveblobs)-1): +# for j in range(i, len(staveblobs)): +# a = staveblobs[i] +# b = staveblobs[j] +# atop = a['rect']['x'] +# abot = a['rect']['x'] + a['rect']['height'] +# btop = b['rect']['x'] +# bbot = b['rect']['x'] + b['rect']['height'] +# if atop > btop and a + + + def remove_ossia(self): + img = self.img + + ossia_mask = np.ones(self.img.shape[:2], dtype="uint8") * 255 + + (staveblobs, otherblobs) = self.find_staveblobs() + staff_heights = map(lambda s: max_staff_height(s), staveblobs) + staff_height = max(staff_heights) + height_thresh = staff_height * 0.75 + + ossias = filter(lambda s: max_staff_height(s) < height_thresh, staveblobs) + + print("blobs %d/%d" % (len(staveblobs), len(otherblobs))) + #staves = self.find_staves(img) + + working_img = img.copy() + + for blob in staveblobs: + miny = self.imgHeight + for staff in blob['staves']: + staffline = staff[0] + miny = min(min(staffline.y_list),miny) + cv2.line(working_img, (0,miny-4), (self.imgWidth,miny-4), (255,255,255), 4) + + cv2.imwrite('test.png', working_img) + + (staveblobs, otherblobs) = self.find_staveblobs(img=working_img) + print("blobs %d/%d" % (len(staveblobs), len(otherblobs))) + i = 0 +# for blob in otherblobs[112:113]: + for blob in otherblobs: + if blob['rect']['width'] < (self.imgWidth / 50): + continue +# if blob['rect']['width'] > (self.imgWidth / 2): +# continue + + src = self.img + mask = np.zeros((self.imgHeight,self.imgWidth,1), np.uint8) + cv2.drawContours(mask, [blob['contour']], -1, (255,255,255), -1); + inv = cv2.bitwise_not(src) + dest = cv2.bitwise_and(inv,inv,mask = mask) + dest = cv2.bitwise_not(dest) + cropped = self.blob_image(dest, blob) + + gi = numpy_io.from_numpy(cropped) + #sf = stafffinder_projections.StaffFinder_projections(gi) + #sf = stafffinder_miyao.StaffFinder_miyao(gi) + sf = stafffinder_dalitz.StaffFinder_dalitz(gi) + sf.find_staves() + staves = sf.get_skeleton() + + if (len(staves) > 0): + maxlines = max(map(len, staves)) + else: + maxlines = 0 + if maxlines >= 4: + print("aha ossia with %d lines" % (maxlines,)) + ossias.append(blob) + for ossia in ossias: + if self.debug: + fn = 'removed_%d.png' % i + cv2.imwrite(fn, cropped) + i = i + 1 + cv2.drawContours(ossia_mask, [ossia['contour']], -1, 0, -1) + + # erode a little to get rid of 'ghosting' around ossia + kernel = np.ones((4,4),np.uint8) + ossia_mask=cv2.erode(ossia_mask,kernel,iterations=4) + + #cv2.imwrite('posterode.png', mask) + + result = img.copy() + inverted = cv2.bitwise_not(result) + result = cv2.bitwise_or(inverted,inverted,mask=ossia_mask) + result = cv2.bitwise_not(result) + + if self.debug: + cv2.imwrite('debug.png', self.debug_img) + + self.img = result + + def split_movements(self, outfileA, outfileB): + # 2% of page width + indentThresh = 0.02 * self.imgWidth + + systems, blobs = self.find_systems() + + # Top - down order + systems = sorted(systems, key=lambda system: system['rect']['y']) + + xs = [] + for system in systems: + xs.append(system['stave_min_x']) + threshold = min(xs) + indentThresh + + # Skip the first one, we don't split if the movement starts at top + # of page + found = None + for i in range(0,len(systems)): + #cv2.imwrite("system%d.png" %i, systems[i]['image']) + if xs[i] > threshold: + if found != None: + print "Oops, more than one movement found." + found = i + print("New movement at system %d" % (i+1)) + + if (found == 0): + self.save_systems(outfileA, systems) + else: + self.save_systems(outfileA, systems[:found]) + self.save_systems(outfileB, systems[found:]) + return(found) + + def save(self, outfile): + cv2.imwrite(outfile, self.img) + + def save_systems(self, outfile, systems): + print "saving %s" % outfile + contours = [] + for system in systems: + contours.append(system['contour']) + + for blob in self.blobs: + if blob['parent'] == system: + contours.append(blob['contour']) + + mask = np.zeros((self.imgHeight,self.imgWidth,1), np.uint8) + + cv2.drawContours(mask, contours, -1, 255, -1); + + kernel = np.ones((4,4),np.uint8) + mask=cv2.dilate(mask,kernel,iterations=1) + + inv = cv2.bitwise_not(self.img) + dest = cv2.bitwise_and(inv,inv,mask = mask) + dest = cv2.bitwise_not(dest) + cv2.imwrite(outfile,dest) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Process/Clustering.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,295 @@ +''' +Created on 10/11/2014 + +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +Class related to Phylogenetic trees + +''' +import copy +import numpy +from Bio import Phylo +from cStringIO import StringIO + +class cluster: + ''' + cluster object for Clustering class + ''' + pass + +class Clustering: + ''' + This class allows to transform a triangular matrix + in a philogenetic tree cutting it at some point + + + usage: + ### The omr name array + species = [ "omr1", "omr2", "omr3", "omr4", "omr5","omr6" ] + matr = [ [ 0., 6., 8., 1., 2. ,6. ], + [ 0., 0., 8., 6., 6. ,4. ], + [ 0., 0., 0., 8., 8. ,8. ], + [ 0., 0., 0., 0., 2. ,6. ], + [ 0., 0., 0., 0., 0. ,6. ], + [ 0., 0., 0., 0., 0. ,0. ], ] + + clustering=Clustering() + ### Transforms the triangular matrix in a complete matrix + matr= clustering.getCompleteMatrix(matr) + + ### establishes the clusters + clu = clustering.make_clusters(species) + + ### Regroup the cluster + tree = clustering.regroup(clu, matr) + + ### get the string in newick format + strTree=clustering.getStringTree(tree,tree.height,"") + + print(strTree) + clustering.showTree(strTree) + + ### Takes the main tree with 5 branches + maintree=clustering.getBetterTree(tree,5) + strTree=clustering.getStringTree(maintree,maintree.height,"") + print(strTree) + clustering.showTree(strTree) + + ''' + + def make_clusters(self,species): + ''' + Organises the cluster based on the species array + ''' + clusters = {} + Id = 1 + for s in species: + c = cluster() + c.id = Id + c.data = s + c.size = 1 + c.height = 0 + clusters[c.id] = c + Id = Id + 1 + return clusters + + def __find_min(self,clu, d): + ''' + finding the minimum distance + private function + ''' + mini = None + i_mini = 0 + j_mini = 0 + for i in clu: + for j in clu: + if j>i: + tmp = d[j -1 ][i -1 ] + if not mini: + mini = tmp + if tmp <= mini: + i_mini = i + j_mini = j + mini = tmp + return (i_mini, j_mini, mini) + + def regroup(self,clusters, dist): + ''' + organizing the cluster + ''' + i, j, dij = self.__find_min(clusters, dist) + ci = clusters[i] + cj = clusters[j] + # create new cluster + k = cluster() + k.id = max(clusters) + 1 + k.data = (ci, cj) + k.size = ci.size + cj.size + k.height = dij / 2. + # remove clusters + del clusters[i] + del clusters[j] + # compute new distance values and insert them + dist.append([]) + for l in range(0, k.id -1): + dist[k.id-1].append(0) + for l in clusters: + dil = dist[max(i, l) -1][min(i, l) -1] + djl = dist[max(j, l) -1][min(j, l) -1] + dkl = (dil * ci.size + djl * cj.size) / float (ci.size + cj.size) + dist[k.id -1][l-1] = dkl + # insert the new cluster + clusters[k.id] = k + + if len(clusters) == 1: + # we're through ! + return clusters.values()[0] + else: + return self.regroup(clusters, dist) + + def __pprint(self,tree, length): + ''' + print the tree in newick format + (A:0.1,B:0.2,(C:0.3,D:0.4):0.5); distances and leaf names + ''' + if tree.size > 1: + # it's an internal node + print "(", + self.__pprint(tree.data[0], tree.height) + print ",", + self.__pprint(tree.data[1], tree.height) + print ("):%2.2f" % (length - tree.height)), + else : + # it's a leaf + print ("%s:%2.2f" % (tree.data, length)), + + def getStringTree(self,tree, length,strOut): + ''' + returns the string of the tree in newick format + (A:0.1,B:0.2,(C:0.3,D:0.4):0.5); distances and leaf names + ''' + if tree.size > 1: + # it's an internal node + strOut+="(" + strOut=self.getStringTree(tree.data[0], tree.height,strOut) + strOut+="," + strOut=self.getStringTree(tree.data[1], tree.height,strOut) + strOut+="):"+str(length- tree.height) + else : + # it's a leaf + strOut+=str(tree.data)+":"+str(length) + return strOut + + + def createClusters(self,tree,length): + ''' + separates the tree at the point determined by length + ''' + clusters=[] + self.__separateClusters(clusters,tree,length) + self.clusters=self.__filterClusters(clusters,length) + return clusters + + def getLeafs(self,tree): + ''' + returns the number of leafs from a tree + ''' + leafs=[] + self.getTreeLeafs(leafs,tree,tree.height) + return leafs + + def __separateClusters(self,clusters,tree,length): + ''' + divides the main tree in multiples trees based on the length + ''' + if tree.size > 1: + if tree.height>=length: + clusters.append(tree.data[0]) + clusters.append(tree.data[1]) + else: + pass + self.__separateClusters(clusters,tree.data[0], length) + self.__separateClusters(clusters,tree.data[1], length) + + def __filterClusters(self,clusters,length): + ''' + removes trees higher than length + ''' + clustersOut=[] + for c in clusters: + if c.height<length: + clustersOut.append(c) + return clustersOut + + def getTreeLeafs(self,leafs,tree,length): + ''' + returns the number of leafs from a tree. Recursive function + ''' + if tree.size > 1: + # it's an internal node + self.getTreeLeafs(leafs,tree.data[0], tree.height) + self.getTreeLeafs(leafs,tree.data[1], tree.height) + else : + # it's a leaf + leafs.append(tree.data) + + def getBetterTree(self,tree,numberLeafs): + ''' + takes the smallest tree that has <= numberLeafs + ''' + while True: + leafs=self.getLeafs(tree) + if len(leafs)<=numberLeafs: + return tree + clusters=self.createClusters(tree,tree.height) + tree=self.getMainTree(clusters) + + + def getAverageDistance(self,matr): + ''' + returns the average distance from the matrix + ''' + sumat=0 + lengthMatrix=len(matr[0]) + length=lengthMatrix*lengthMatrix-lengthMatrix + for i in range(lengthMatrix): + for j in range(lengthMatrix): + sumat=sumat+matr[i][j] + return (sumat/length)/2 + + def getMaximumDistance(self,matr): + ''' + returns the maximum distance from the matrix + ''' + maxValue=0 + lengthMatrix=len(matr[0]) + for i in range(lengthMatrix): + for j in range(lengthMatrix): + if matr[i][j]>maxValue: + maxValue=matr[i][j] + return maxValue/2 + + def getMainTree(self,clusters): + ''' + Takes the tree with the higher number of leafs + ''' + maxim=0 + indexmax=0 + for i in range(len(clusters)): + leafs=self.getLeafs(clusters[i]) + if len(leafs)>maxim: + maxim=len(leafs) + indexmax=i + + return clusters[indexmax] + + def getCompleteMatrix(self,matr): + ''' + return the complete matrix from a + triangular matrix + ''' + newMatrix=copy.copy(matr) + if isinstance(matr,numpy.ndarray): + newMatrix=newMatrix.tolist() + lengthMatrix=len(matr[0]) + for i in range(lengthMatrix): + for j in range(i,lengthMatrix): + newMatrix[j][i]=matr[i][j] + return newMatrix + + def showTree(self,strTree): + ''' + Shows a graphical representation from a newick tree format + ''' + handle = StringIO(strTree) + tree = Phylo.read(handle, 'newick') + tree.ladderize() + # Phylo.draw(tree) + Phylo.draw_ascii(tree) + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Process/FullScoreAlignment.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,162 @@ +''' +Created on 10/11/2014 + +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +Functions related to the full score alignment. +It takes the n parts and align with the best omr full score +for the missing rest measuress +''' +from music21 import converter +from music21 import stream +from Functions import HashFunctions +from Functions import FilesFunctions + + +class FullScoreAlignment: + ''' + Class for the full score alignment + + usage: + + fsa=FullScoreAlignment() + idCompleteScoreBetter=fsa.getIdBetterOMRFullScore(fsOMRs,partsNumber) + finalScore=fsa.runSynchronisingMeasuresNJ(subdirnameFullScore,subdirnameParts,fsOMRs[idCompleteScoreBetter]) + finalScore.write("musicxml", dirGeneral+'/finalScore.xml') + + ''' + def runSynchronisingMeasuresNJ(self,subdirnameParts,completeScore): + ''' + This function takes the different result.S2.xml files to construct + the final output. + + Example: + fsa=FullScoreAlignment() + idCompleteScoreBetter=fsa.getIdBetterOMRFullScore(fsOMRs,partsNumber) + finalScore=fsa.runSynchronisingMeasuresNJ(subdirnameFullScore,subdirnameParts,fsOMRs[idCompleteScoreBetter]) + finalScore.write("musicxml", dirGeneral+'/finalScore.xml') + ''' + + gapOMRs=[] + parts=[] + completeScoreParts=[] + + # Convert to Hash the better full score + hf=HashFunctions() + for p in completeScore.getElementsByClass(stream.Part): + sc=stream.Score() + sc.append(p) + completeScoreParts.append(sc) + completeScoreHash=hf.getHash(completeScoreParts) + + # Convert to hash the parts + for dirname in sorted(subdirnameParts): + print "--- ",dirname + path = dirname+"/XML/" + partId=int(dirname.split('\\')[-1]) + print partId + resultS2File=path+ "result.S2.xml" + resultS2=converter.parse(resultS2File,forceSource=False) + parts.append(resultS2) + partsHash=hf.getHash(parts) + + + for partHash in partsHash: + index=partsHash.index(partHash) + h=[] + h.append(partHash) + h.append(completeScoreHash[index]) + hf.alignHash(h) + partsHash[index]=h[0] + completeScoreHash[index]=h[1] + + gaps=hf.getGapsFromHashArray(h) + gapOMRs.append(gaps) + if(index<len(partsHash)-1): + nextPart=completeScoreHash[index+1] + for gap in gaps[1]: + nextPart.insert(gap,"*") + + print "--------------trace back-----------" + print gapOMRs + sc=stream.Score() + gaps=gapOMRs[len(partsHash)-1][1] + for i in range(len(partsHash)-1): + completeScoreHash[i]=hf.removeHashGaps(completeScoreHash[i]) + completeScoreHash[i]=hf.addHashGaps(completeScoreHash[i],gaps) + partsHash[i]=hf.removeHashGaps(partsHash[i]) + h=[] + h.append(partsHash[i]) + h.append(completeScoreHash[i]) + + h=hf.alignHash(h) + partsHash[i]=h[0] + completeScoreHash[i]=h[1] + + print "--------------reconstruct scores-----------" + + streams,gaps=hf.reconstructHash(parts,partsHash) + for s in streams: + part=s.getElementsByClass(stream.Part)[0] + sc.append(part) + return sc + + + + def getIdBetterOMRFullScore(self,fsOMRs_files,partsNumber): + ''' + Tries to obtain the best full omr score + based on the parts and the length. + + Omrs increase the part numbers and add new rest measures + to synchronize + + usage: + # fsOMRs is an array with the full score omrs + # for string quartet, 4 parts + idCompleteScoreBetter=fsa.getIdBetterOMRFullScore(fsOMRs,4) + + + ''' + print "---------Calculating better OMR for alignment------------" + ff=FilesFunctions() + measuresLengthBetter=1000000 #maximum + partsLengthBetter=1000 #maximum + idCompleteScoreBetter=1000 #maximum + for cs_file in fsOMRs_files: + cs=ff.getOMR(cs_file) + if cs!=[]: + try: + isEqualParts=False + isLessMeasures=False + isBetterOMR=False + idCompleteScore=fsOMRs_files.index(cs_file) + measuresLength=len(cs.getElementsByClass(stream.Part)[0].getElementsByClass(stream.Measure)) + partsLength=len(cs.getElementsByClass(stream.Part)) + print idCompleteScore,measuresLength,partsLength + + if(partsLength==partsNumber): + isEqualParts=True + if(measuresLength<measuresLengthBetter): + isLessMeasures=True + + if isLessMeasures and isEqualParts: + isBetterOMR=True + if isBetterOMR: + idCompleteScoreBetter=idCompleteScore + measuresLengthBetter=measuresLength + partsLengthBetter=partsLength + except: + print "error OMR" + print idCompleteScoreBetter,measuresLengthBetter,partsLengthBetter + return idCompleteScoreBetter + + + + + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Process/PipelineAlignment.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,372 @@ +''' +Created on 10/11/2014 + +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +Functions related to the alignment +and voting process +''' +from Alignment import FastAlignmentArrays +from SymbolConversion import SymbolConversion +from Functions import FilesFunctions +import numpy as np +from Clustering import Clustering +import math +from Alignment import NWunsch + + +class PipelineAlignment: + def alignGround(self,OMRs,part): + ''' + Returns one part and the ground aligned. The first array value of OMRs + should be the ground and the second the omr to align + ''' + sc=SymbolConversion() + OMRs_symbols=[] + omr_symbolsAlign=[] + for omr in OMRs: + omr_symbols=sc.filterOMR(omr,part)[1] + OMRs_symbols.append(omr_symbols) + omr_symbolsAlign.append([]) + + faa=FastAlignmentArrays() + out=faa.needleman_wunsch(OMRs_symbols[0], OMRs_symbols[1])[0] + + + return out + + def getDistances(self,OMRs_symbols): + ''' + Returns the distance matrix from several omr + in symbols, using the first symbol only + [u'N:E-4_0.25', 0.25, '', 2.75, 3.0, None] y + [u'N:E-4_0.25', 0.33, '', 2.50, 2.75, None] + + are equals + + Returns a triangular matrix + [[ 0. 0.17647058 0.19141912] + [ 0. 0. 0.17647058] + [ 0. 0. 0. ]] + + Uses the algorithm implemented in C for increasing the speed + Alignment/C_Libraries/NWunsch + ''' + ls=len(OMRs_symbols) + dimension= (ls,ls) + distances=np.zeros(dimension) + for i in range(len(OMRs_symbols)): + for j in range(i+1,len(OMRs_symbols)): + print i,j + align1=[] + align2=[] + for s in OMRs_symbols[i]: + align1.append(s[0]) + for s in OMRs_symbols[j]: + align2.append(s[0]) + #Algorithm implemented in C + if len(align1)==0 or len(align2)==0: + score=0 + else: + print"-------------------------" + + score=NWunsch.NWunsch_getSimilarity(align1,align2) + print"-------------------------" + if math.isnan(score): + score=0 + distances[i][j]=1-score + return distances + + def getDistanceLength(self,OMRs_symbols): + ''' + Similar to getDistance, but based on the length + of the omrs. Testing purposes + ''' + ls=len(OMRs_symbols) + dimension= (ls,ls) + distances=np.zeros(dimension) + for i in range(len(OMRs_symbols)): + for j in range(i+1,len(OMRs_symbols)): + print i,j + len_i=len(OMRs_symbols[i]) + len_j=len(OMRs_symbols[j]) + maxLen=len_j + if len_i>=len_j: + maxLen=len_i + + score=(len_i-len_j)*1.0/maxLen + if score<0: + score=score*-1 + distances[i][j]=score + return distances + + def __getMinimum(self,distance): + ''' + Returns the minimum value and the x,y position + in the distance matrix + ''' + minim=1000 + iMin=0 + jMin=0 + for i in range(len(distance[0])): + for j in range(i+1,len(distance[0])): + dist=distance[i][j] + if isinstance(dist,list): + dist=dist[0] + if dist<minim: + minim=dist + iMin=i + jMin=j + + return minim,iMin,jMin + + + def __recalculeDistances(self,distance,iMin,jMin): + ''' + Removes the rows and the column in the distance matrix + and calculates the new matrix + ''' + for i in range(len(distance[0])): + for j in range(i+1,len(distance[0])): + if j==iMin: + dist=distance[i][j] + dist2=distance[i][jMin] + distance[i][j]=(dist+dist2)/2 + distance=np.delete(distance, jMin, 0) + distance=np.delete(distance, jMin, 1) + return distance + + + def __getPairingReal(self,iMin,jMin,removedArray): + ''' + Returns the real omr position in the original matrix + based on the actual position and the elements removed + + usage: + self._getPairingReal(0,1,[1]) + returns + 0,2 + ''' + iMinReal=iMin + jMinReal=jMin + removedArray.sort() + for removedItem in removedArray: + if iMinReal>=removedItem: + iMinReal+=1 + if jMinReal>=removedItem: + jMinReal+=1 + return iMinReal,jMinReal + + def selectBetterOMRs(self,OMRs_symbols): + ''' + Based on Philogenetic trees, this function + takes the best omrs based on the distances between them + ''' + distanceSimple=self.getDistances(OMRs_symbols) + clustering=Clustering() + distances=clustering.getCompleteMatrix(distanceSimple) + species = [] + for i in range(len(OMRs_symbols)): + species.append(i) + clu = clustering.make_clusters(species) + tree = clustering.regroup(clu, distances) + + #at least 3 leafs in the tree + maintree=tree + for i in range(3,len(OMRs_symbols)): + maintree=clustering.getBetterTree(tree,i) + if len(clustering.getLeafs(maintree))>=3: + break + + + betterOmrIds= clustering.getLeafs(maintree) + + #Graphic representation + strTree=clustering.getStringTree(tree,tree.height,"") + print strTree + clustering.showTree(strTree) + strMainTree=clustering.getStringTree(maintree,maintree.height,"") + print strMainTree + clustering.showTree(strMainTree) + + newOMRs=[] + for i in betterOmrIds: + newOMRs.append(OMRs_symbols[i]) + + return newOMRs,betterOmrIds + +# def alignNJ(self,idPart,fsOMRs,partOMRs): +# ''' +# Main function for aligning the different OMRs +# +# Returns: +# omr_symbolsAligned. OMR array of symbols aligned (only the best) +# betterOmrIds. Id array of better OMRs (for writing the log file) +# +# usage: +# pa=PipelineAlignment() +# omr_symbolsAligned,betterOmrIds=pa.alignNJ(idPart,fsOMRs,partOMRs) +# ''' +# +# +# OMRs_symbols=[] +# sc=SymbolConversion() +# print "2---converting to symbols---" +# for omr in OMRs: +# if omr!=[]: +# omr_symbols=sc.filterOMR(omr,idPart)[1] +# OMRs_symbols.append(omr_symbols) +# else: +# OMRs_symbols.append([]) +# +# print "3---removing worst OMR---" +# # betterOmrIds=[] +# OMRs_symbols,betterOmrIds=self.selectBetterOMRs(OMRs_symbols) +# +# print "4---calculating distances---" +# distances=self.getDistances(OMRs_symbols) +# +# print "5---aligning symbols---" +# +# omr_symbolsAligned=self.setOMRSymbolsAligned(OMRs_symbols,distances) +# +# return omr_symbolsAligned,betterOmrIds + + def alignNJ_files(self,idPart,fsOMRs_files,partOMRs_files): + ''' + Main function for aligning the different OMRs + + Returns: + omr_symbolsAligned. OMR array of symbols aligned (only the best) + betterOmrIds. Id array of better OMRs (for writing the log file) + + usage: + pa=PipelineAlignment() + omr_symbolsAligned,betterOmrIds=pa.alignNJ(idPart,fsOMRs,partOMRs) + ''' + + + ff=FilesFunctions() + OMRs_files=partOMRs_files+fsOMRs_files + OMRs_symbols=[] + sc=SymbolConversion() + print "2---converting to symbols---" + for omr_file in OMRs_files: + omr=ff.getOMR(omr_file) + if omr!=[]: + omr_symbols=sc.filterOMR(omr,idPart)[1] + OMRs_symbols.append(omr_symbols) + else: + OMRs_symbols.append([]) + + print "3---removing worst OMR---" +# betterOmrIds=[] + + + OMRs_symbols,betterOmrIds=self.selectBetterOMRs(OMRs_symbols) + + print "4---calculating distances---" + distances=self.getDistances(OMRs_symbols) + + print "5---aligning symbols---" + + omr_symbolsAligned=self.setOMRSymbolsAligned(OMRs_symbols,distances) + + return omr_symbolsAligned,betterOmrIds + def __setVoidArray(self,length): + ''' + private function to create a void array + ''' + arrayOut=[] + for _ in range(length): + arrayOut.append([]) + + return arrayOut + + def setOMRSymbolsAligned(self,OMRs_symbols,distances): + ''' + returns the OMRs symbols aligned from OMR symbols and + the distances matrix + ''' + pairings=[] + pairingsReal=[] + gapArray=[] + removedArray=[] + omr_symbolsAlign=self.__setVoidArray(len(OMRs_symbols)) + faa=FastAlignmentArrays() + while len(distances[0])>1: + minim,iMin,jMin=self.__getMinimum(distances) + print distances,minim,iMin,jMin + pairings.append([iMin,jMin]) + iMinReal,jMinReal=self.__getPairingReal(iMin,jMin,removedArray) + + pairingsReal.append([iMinReal,jMinReal]) + if len(omr_symbolsAlign[iMinReal])==0: + omr_symbolsAlign[iMinReal]=OMRs_symbols[iMin] + if len(omr_symbolsAlign[jMinReal])==0: + omr_symbolsAlign[jMinReal]=OMRs_symbols[jMin] + + out=faa.needleman_wunsch(omr_symbolsAlign[iMinReal], omr_symbolsAlign[jMinReal])[0] + omr_symbolsAlign[iMinReal]=out[0] + omr_symbolsAlign[jMinReal]=out[1] + gap1=out[2] + gap2=out[3] + gapArray.append([gap1,gap2]) + + + OMRs_symbols.pop(jMin) + removedArray.append(jMinReal) + + distances=self.__recalculeDistances(distances,iMin,jMin) + + + omr_symbolsAlign=self.__fillingGaps(omr_symbolsAlign,gapArray,pairingsReal) + + + return omr_symbolsAlign + + def __fillingGaps(self,omr_symbolsAlign,gapArray,pairingsReal): + ''' + private function to complete gaps based on the gap matrix + and the pairs stablished + ''' + for p in range(len(pairingsReal)-1,0,-1): + for i in range(2): + for j in range(2): + for t in range(1,p+1): + if(pairingsReal[p][i]==pairingsReal[p-t][j]): + if j==0: + s=1 + if j==1: + s=0 + omrIndex=pairingsReal[p-t][s] + newGap=[] + for gap in gapArray[p][i]: + omr_symbolsAlign[omrIndex].insert(gap,"*") + newGap.append(gap) + gapArray[p-t][s]=gapArray[p-t][s]+newGap + + + return omr_symbolsAlign + + + + + + + + + + + + + + + + + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Process/SymbolConversion.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,575 @@ +''' +Created on 10/11/2014 + +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +Functions related to convert music21 output +to symbols for aligning and voting +''' +from music21 import note +from music21 import chord +from music21 import meter +from music21 import key +from music21 import stream +from music21 import tie +from music21 import bar +from music21 import harmony +from music21 import clef +class SymbolConversion: + + + def __getSymbolMesure(self,symbol): + ''' + Detects if it is a barline symbol and gets the first element + ''' + if isinstance(symbol,list): + if symbol[0].find('!')!=-1: + return symbol + + def convertM21(self,symbolArray): + ''' + Converts one Array of symbols to music21 + + usage: + + outVote=vote.vote(omr_symbolsAlign) + #apply voices if it is needed + + outVote=sc.setVoices(outVote) + #convert to music21 + resultS2=sc.convertM21(outVote) + + ''' + + sOut=stream.Score() + sPart=stream.Part() + measureIndex=1 + measure=stream.Measure() + measure.number=measureIndex + voicesLength=8 + for v in range(voicesLength): + voice=stream.Voice() + voice.id=v + measure.append(voice) + indexS=0 + + for symbol in symbolArray: + mytie="" + realDuration=None + s=symbol + + if isinstance(s,list): + s=s[0] + if s.find('TS:')!=-1: + ts=meter.TimeSignature(s[3:]) + + measure.append(ts) + if s.find('KS:')!=-1: + k=key.KeySignature(int(s[3:])) + + measure.append(k) + if s.find('CL:')!=-1: + c=clef.clefFromString(str(s[3:])) + + measure.append(c) + if s.find('N:')!=-1: + try: + if isinstance(symbol,list): + realDuration=symbol[1] + mytie=symbol[2] + + sep=s.index("_") + duration=s[sep+1:] + #************************************* + #duration vs realDuration for triplets + if realDuration!=None: + duration=realDuration + #************************************* + if(float(duration)>0): + n=note.Note(s[2:sep],quarterLength=float(duration)) + if symbol[5]!=None: + n.color=symbol[5] + if mytie!="": + n.tie=tie.Tie(mytie) + if len(symbol)>6:#voices + measure.voices[symbol[6]].append(n) + else: + measure.append(n) + except: + print "error"+s + + if s.find('R:')!=-1: + try: + if isinstance(symbol,list): + realDuration=symbol[1] + mytie=symbol[2] + duration=s[2:] + #************************************* + #duration vs realDuration for triplets + if realDuration!=None: + duration=realDuration + #************************************* + n=note.Rest(quarterLength=float(duration)) + if symbol[5]!=None: + n.color=symbol[5] + if len(symbol)>6:#voices + measure.voices[symbol[6]].append(n) + else: + measure.append(n) + except: + print "error"+s + + if s.find('C:')!=-1: + notes=s.split("[:") + cPitch=[] + for n in notes: + if n!='C:': + sep=n.index("_") + duration=n[sep+1:] + pitch= n[0:sep] + cPitch.append(pitch) + c=chord.Chord(cPitch) + c.duration.quarterLength=float(duration) + if symbol[5]!=None: + c.color=symbol[5] + if mytie!="": + c.tie=tie.Tie(mytie) + + if len(symbol)>6:#voices + measure.voices[symbol[6]].append(c) + else: + measure.append(c) + + if s.find('!')!=-1: + if isinstance(symbol,list): + barType= symbol[1] + barRepeat= symbol[2] + if barType!="": + try: + mybartype=bar.styleToMusicXMLBarStyle(barType) + myBar=bar.Barline(style=mybartype) + measure.rightBarline=myBar + except: + print "error barline" + + if barRepeat!="": + try: + myBar=bar.Repeat(direction=barRepeat) + if barRepeat=="start": + measure.leftBarline=myBar + if barRepeat=="end": + measure.rightBarline=myBar + except: + print "error barline" + sPart.append(measure) + measureIndex+=1 + measure=stream.Measure() + measure.number=measureIndex + for v in range(voicesLength): + voice=stream.Voice() + voice.id=v + measure.append(voice) + + indexS+=1 + + sOut.append(sPart) + return sOut + + + + + def __orderChord(self,mychord): + ''' + Private function that returns a chord ordered + in a string from lower to higher + ''' + midi=[] + midi2=[] + orderC=[] + for n in mychord: + if isinstance(n,note.Note): + midi.append(n.midi) + midi2.append(n.midi) + + while len(midi)>0: + indexMin=midi2.index(min(midi)) + indexPop=midi.index(min(midi)) + orderC.append(mychord[indexMin]) + midi.pop(indexPop) + + myOrderChord=chord.Chord(orderC) + myOrderChord.duration.quarterLength=mychord.duration.quarterLength + return myOrderChord + + + def __getKeyOffset(self,item): + ''' + Private function that returns the offset of one item + ''' + return item['offset'] + + def __removeDuplicates(self,input_raw): + ''' + Private function to remove duplicates in the string input + ''' + seen = set() + new_l = [] + for d in input_raw: + t = tuple(d.items()) + if t not in seen: + seen.add(t) + new_l.append(d) + + return new_l + + + def getElementsFromMeasureOrderByOffset(self,measure): + ''' + Returns the symbols of a measure ordered by offset + ''' + offset=measure.flat.offsetMap + offset_n=self.__removeDuplicates(offset) + sorted_offset=sorted(offset_n,key=self.__getKeyOffset) + return sorted_offset + + def __swapSymbols(self,s1,s2): + ''' + Swap the s1,s2 symbols + ''' + inter=s1 + s1=s2 + s2=inter + return s1,s2 + + def orderSymbolsByPitch(self,symbols): + ''' + Orders the symbol string from lower to high if they have + the same offset + ''' + for i in range(len(symbols)-1): + for j in range(i,i+2): + pitch_i=0 + pitch_j=0 + if(symbols[i]['offset']==symbols[j]['offset']): + if isinstance(symbols[i]['element'],note.Note): + pitch_i=symbols[i]['element'].pitch.midi + if isinstance(symbols[j]['element'],note.Note): + pitch_j=symbols[j]['element'].pitch.midi + + if pitch_j>pitch_i:#higher pitch first + symbols[i],symbols[j]=self.__swapSymbols(symbols[i],symbols[j]) + + if pitch_j==pitch_i and pitch_j>0:#longest first if equal pitch + if symbols[i]['element'].duration<symbols[j]['element'].duration: + symbols[i],symbols[j]=self.__swapSymbols(symbols[i],symbols[j]) + + if isinstance(symbols[j]['element'],note.Rest):#rest first + symbols[i],symbols[j]=self.__swapSymbols(symbols[i],symbols[j]) + + return symbols + + def getRepetitionMarks(self,measure): + ''' + Returns the repetition marks symbol from a measure + ''' + symbols=[] + for barline in measure.getElementsByClass(bar.Barline): + symbol={'voiceIndex': None, 'element': barline, 'endTime': 0.0, 'offset': barline.offset} + symbols.append(symbol) + return symbols + + def getTS(self,measure): + ''' + Returns the time signature symbol from a measure + ''' + symbols=[] + for ts in measure.getElementsByClass(meter.TimeSignature): + symbol={'voiceIndex': None, 'element': ts, 'endTime': 0.0, 'offset': ts.offset} + symbols.append(symbol) + return symbols + + def removeTS(self,symbols): + ''' + Removes the time signature from the symbols array + ''' + for symbol in symbols: + s=symbol['element'] + if 'TimeSignature' in s.classes: + symbols.pop(symbols.index(symbol)) + break + return symbols + + def filterOMR(self,omr,idPart): + ''' + Removes elements from the music21 input as text, slurs and expressions (p, mp, f...) + + Returns the omr filtered and the symbols array converted + + ''' + omr_filtered=stream.Stream() + omr_symbols=[] + #for single parts + print "Partes=",len(omr.parts) + if len(omr.parts)==1: + idPart=0 + if len(omr.parts)==0: + idPart=0 + mypart=omr + if len(omr.parts)>=1: + if(int(idPart)>=len(omr.parts)): + print "error in OMR" + return [],[] + mypart=omr.parts[int(idPart)] + + + + isFirstClef=True + indexMes=0 + print idPart + for measure in mypart.getElementsByClass(stream.Measure): + indexMes+=1 + symbols=self.getElementsFromMeasureOrderByOffset(measure.semiFlat)#key signature time signature and clef are missing if not flat + symbols=self.orderSymbolsByPitch(symbols) + symbolsRepetition=self.getRepetitionMarks(measure) + symbolsTS=self.getTS(measure) + symbols=self.removeTS(symbols) + symbols=symbolsTS+symbols+symbolsRepetition + + newMeasure=stream.Measure() + styleBarline="" + directionRepeat="" + strClef="" + + for symbol in symbols: + #symbol={'voiceIndex': 0, 'element': <music21.note.Note C>, 'endTime': 1.0, 'offset': 0.0} + s=symbol['element'] + if 'TimeSignature' in s.classes: + newMeasure.append(s) + str0="TS:"+str(s.numerator)+"/"+str(s.denominator) + omr_symbols.append([str0,None,None,symbol['offset'],symbol['endTime'],None]) + + elif 'KeySignature' in s.classes: + newMeasure.append(s) + str0="KS:"+str(s.sharps) + omr_symbols.append([str0,None,None,symbol['offset'],symbol['endTime'],None]) + + elif 'Clef' in s.classes: + newMeasure.append(s) + strClef="CL:"+str(s.sign) + if isFirstClef: + omr_symbols.append([strClef,None,None,symbol['offset'],symbol['endTime'],None]) + strClef="" + isFirstClef=False + + elif 'Note' in s.classes: + newMeasure.append(s) + mytype=s.duration.type + duration=note.duration.convertTypeToQuarterLength(mytype) + realDuration=s.duration.quarterLength + if realDuration==duration+duration/2: #dot case + duration=realDuration + n="N:"+s.pitch.nameWithOctave+"_"+str(duration) + # Ties case + mytie="" + if s.tie!=None: + mytie=s.tie.type + + if float(realDuration)>0: + omr_symbols.append([n,realDuration,mytie,symbol['offset'],symbol['endTime'],s.color] ) + + elif 'Rest' in s.classes: + newMeasure.append(s) + mytype=s.duration.type + if mytype!="complex": + duration=note.duration.convertTypeToQuarterLength(mytype) + else: + duration=s.duration.quarterLength + realDuration=s.duration.quarterLength + if realDuration==duration+duration/2: #dot case + duration=realDuration + n="R:"+str(duration) +# realDuration=s.duration.quarterLength + omr_symbols.append([n,realDuration,False,symbol['offset'],symbol['endTime'],s.color]) + + elif 'Chord' in s.classes: + if type(s) is not harmony.ChordSymbol: + newMeasure.append(s) + mytype=s.duration.type + duration=note.duration.convertTypeToQuarterLength(mytype) + realDuration=s.duration.quarterLength + if realDuration==duration+duration/2: #dot case + duration=realDuration + chord="C:" + sOrder=self.__orderChord(s) + for n in sOrder: + chord+="[:"+n.pitch.nameWithOctave+"_"+str(duration) + + + + # Ties case + mytie="" + if s.tie!=None: + mytie=s.tie.type + omr_symbols.append([chord,realDuration,mytie,symbol['offset'],symbol['endTime'],s.color]) + + elif 'Barline' in s.classes: + styleBarline=s.style + try: + directionRepeat=s.direction + except: + directionRepeat="" + + + omr_symbols.append(['!',styleBarline,directionRepeat,symbol['offset'],symbol['endTime'],None]) + if strClef!="": + omr_symbols.append([strClef,None,None,0,0,None]) + omr_filtered.append(newMeasure) + return omr_filtered,omr_symbols + + def removeExtraTies(self,arraySymbols): + ''' + Removes the non logical ties from the symbol array + + ''' + for s in arraySymbols: + if isinstance(s,list): + mainSymbol=s[0] + if mainSymbol.find('N:')!=-1: + tie1=s[2] + if arraySymbols.index(s)<len(arraySymbols): + sNext=arraySymbols[arraySymbols.index(s)+1] + if isinstance(sNext,list): + mainSymbol2=sNext[0] + if mainSymbol2.find('N:')!=-1: + tie2=sNext[2] + if tie1=='start' and tie2!='end': + s[2]='' + + return arraySymbols + + + def setVoices(self,strSymbols): + ''' + Divides each measure in voices, if it is necessary. + + The output is the symbol string using voices + + ''' + quarters=self.__getTimeSignatureQuarters(strSymbols) + measures=self.__chopMeasures(strSymbols) + newString=[] + for measure in measures: + newMeasure=self.divideMeasureinVoices(measure,quarters) + for s in newMeasure: + newString.append(s) + return newString + + def __getTimeSignatureQuarters(self,strSymbols): + ''' + returns the number of quarters of the first time signature found + ''' + quarters=4 #4/4 by default + for s in strSymbols: + if isinstance(s,list): + s=s[0] + if s.find('TS:')!=-1: + ts=s[3:] + timeSig=ts.split("/") + num=int(timeSig[0]) + den=int(timeSig[1]) + quarters=(4/den)*num + return quarters + + def __chopMeasures(self,strSymbols): + ''' + Divides the symbol string in measures + ''' + strMeasures=[] + strMeasure=[] + for s in strSymbols: + strMeasure.append(s) + bar=self.__getSymbolMesure(s) + if bar!=None: + strMeasures.append(strMeasure) + strMeasure=[] + return strMeasures + + + def isNoteRest(self,symbol): + ''' + Returns true if the symbol is note, rest or chord + ''' + s=symbol + if isinstance(s,list): + if s[0].find('N:')!=-1: + return True + if s[0].find('R:')!=-1: + return True + if s[0].find('C:')!=-1: + return True + return False + return False + + def divideMeasureinVoices(self,strMeasure,quarters): + ''' + If the length of each measure in the string is higher than quarters, + adjusting to voices + + ''' + newMeasure=[] + duration=0 + #if duration is higher than time signatura + for s in strMeasure: + if self.isNoteRest(s): + if s[1]!=None: + try: + duration+=s[1] + except: + pass + # voices only if needed + if duration<=quarters: + return strMeasure + + + for s in strMeasure: + if not self.isNoteRest(s): + if self.__getSymbolMesure(s)==None: + newMeasure.append(s) + voiceslength=8 + for v in range(voiceslength-1): + offset=0.0 + firstNote=False + for s in strMeasure: + if self.isNoteRest(s): + if len(s)<7:#not voice yet + offsetNote=s[3] + if firstNote==False: + offset=offsetNote + firstNote=True + if offsetNote>0: + rest=[] + rest.append("R:"+str(offsetNote)) + rest.append(offsetNote) + rest.append(False) + rest.append(0) + rest.append(offsetNote) + rest.append(None) + rest.append(v) + newMeasure.append(rest) + if(offset==offsetNote): + s.append(v) + newMeasure.append(s) + offset=s[4] + + + for s in strMeasure: + if self.__getSymbolMesure(s)!=None: + newMeasure.append(s) + + + return newMeasure \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Process/Voting.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,132 @@ +''' +Created on 12/12/2014 + +@author: victor +''' +class Voting: + + def __getIndicesFromValue(self,value, qlist): + ''' + Return the index in the matrix with that value + ''' + indices = [] + idx = -1 + while True: + try: + idx = qlist.index(value, idx+1) + indices.append(idx) + except ValueError: + break + return indices + + def vote(self,omr_symbolsAlign): + ''' + main function for voting the omr symbol array + + ''' + voteArr=self.getArrayVotation(omr_symbolsAlign) + outArr=self.getVoteResult(omr_symbolsAlign,voteArr) + return outArr + + def getArrayVotation(self,omr_symbolsAlign): + ''' + Returns a matrix with the number of votes of each symbol. + Each symbol is voted individually + + ''' + voteArr=[] + for i in range(len(omr_symbolsAlign[0])): + voteArr.append([]) + + for j in range(len(omr_symbolsAlign)): + vote=[] + for n in range(5): + vote.append(0) + voteArr[i].append([]) + + for k in range(len(omr_symbolsAlign)): + symbol1=omr_symbolsAlign[j][i] + symbol2=omr_symbolsAlign[k][i] + for n in range(5): + if isinstance(symbol1,list) and isinstance(symbol2,list): + if(symbol1[n]==symbol2[n]): + vote[n]+=1.0 + + voteArr[i][j].append(vote) + return voteArr +# + + + def _getNValueArray(self,array,n): + ''' + Takes one slide in the aligned array + ''' + values=[] + for o in array: + value=o[0][n] + values.append(value) + return values + + def __getBetterIndexSymbol(self,a0,a1,a2): + ''' + returns the best symbol based on the first three parameters + [[D5_0.25,0.33,'start'....] + note,realDuration, tie + ''' + symbol_count=[] + for i0 in a0: + s=0 + if i0 in a1: + s=s+10 + if i0 in a2: + s=s+1 + symbol_count.append(s) + better=symbol_count.index(max(symbol_count)) + index=a0[better] + return index + + def getBetterGeneralSymbol(self,omr_symbolsAlign,indexPosition,a): + ''' + reconstruct the symbol using the best 5 parameters + ''' + s=omr_symbolsAlign[a[0][0]][indexPosition] + if isinstance(s,list): + try: + for n in range(5): + s[n]=omr_symbolsAlign[a[n][0]][indexPosition][n] + return s + except: + return s + else: + return s + + def getVoteResult(self,omr_symbolsAlign,voteArr):#voteArr[i][j].append([vote,vote_1,vote_2]) + ''' + Using the symbols aligned and the matrix with the votes. + + One symbol in three omr has this structure + [[[3.0, 2.0, 3.0, 2.0, 2.0]], + [[3.0, 1.0, 3.0, 1.0, 1.0]], + [[3.0, 2.0, 3.0, 2.0, 2.0]]] + + returns the better output + ''' + outArr=[] + for i in range(len(voteArr)): + vote=[] + indexMax_array=[] + for n in range(5): + vote.append([]) + vote[n]=self._getNValueArray(voteArr[i],n) + indexMax_array.append([]) + indexMax_array[n]=self.__getIndicesFromValue(max(vote[n]),vote[n]) + + betterIndex=self.__getBetterIndexSymbol(indexMax_array[0],indexMax_array[1],indexMax_array[2]) + sBetterGeneral=self.getBetterGeneralSymbol(omr_symbolsAlign,i,indexMax_array) + perc=vote[0][betterIndex]/len(vote[0]) + + if perc>=0.5: + outArr.append(sBetterGeneral) + return outArr + + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Process/__init__.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,5 @@ +from Clustering import Clustering +from FullScoreAlignment import FullScoreAlignment +from PipelineAlignment import PipelineAlignment +from SymbolConversion import SymbolConversion +from Voting import Voting
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Result/ExcellData.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,206 @@ +''' +Created on 10/11/2014 + +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +Class for writing data in .xlsx format +It allows writing the results comparing with the ground in .xls + +''' +import xlsxwriter +from openpyxl import load_workbook + +class ExcellData: + def saveData(self,data,files,percentages): + ''' + save the data from one part (one movement) + in the "result.xlsx" file + + usage: + + ed=ExcellData() + ff=FilesFunctions() + OMRs=ff.getOMRs(path) + for omr in OMRs: + OMRs_compare=[] + OMRs_compare.append(groundparsed) + OMRs_compare.append(omr) + + percentage,errors,scoreWithErrors= pg.getSimilarity(OMRs_compare,0) + ErrorsMatrix.append(errors) + percentages.append(percentage) + + ed.saveData(ErrorsMatrix,files,percentages) + ''' + + path=self.__getPathStepsBack(files[0],2) + wb=xlsxwriter.Workbook(path+'\\Result\\result.xlsx') + ws=wb.add_worksheet() + c=0 + ws.write(0, 0,str(files[0])) + + for col in data: + r=2 + ws.write(1, c,str(percentages[c])) + fArray=files[c].split('\\') + ws.write(r, c,str(fArray[-1])) + for row in col: + r+=1 + ws.write(r, c,str(row)) + c+=1 + wb.close() + + def saveGlobalData(self,data,path,betterOMRIds,files): + ''' + Takes the individual parts and store the result + in "resultGeneral.xlsx" + + usage: + ed=ExcellData() + ed.saveGlobalData(percentagesArray,dirGeneral,betterOMRIds,files) + + files=['file1.xml','file2.xml','file3.xml','file4.xml'] + + data=[[0.7 ,0.8, 0.5, 0.6] + [0.7 ,0.8, 0.5, 0.6] + [0.7 ,0.8, 0.5, 0.6]] + + betterOMRIds=[[0,1,2] + [2,3,1] + [1,0,2]] + + ed=ExcellData() + ed.saveGlobalData(percentagesArray,dirGeneral,betterOMRIds,files) + ''' + + + wb=xlsxwriter.Workbook(path+'\\parts\\resultGeneral.xlsx') + ws=wb.add_worksheet() + r=0 + ws.write(0, 1,str(files[0])) + print betterOMRIds + for row in data: + c=0 + myBetterOMR=betterOMRIds[r] + for col in row: + format1 = wb.add_format() + format1.set_font_color('black') + if str(c-1)+"\n" in myBetterOMR: + format1.set_font_color('red') + fArray=files[c].split('\\') + ws.write(0, c,str(fArray[-1])) + ws.write(r+1, c,float(col),format1) + c+=1 + r+=1 + wb.close() + + def processResultGeneral(self,f): + ''' + This function takes one xls file and get the percentage of accuracy of each omr + Returns in this order S2Out,CPOut,PSOut,SEOut,SSOut + ''' + wb = load_workbook(f) + ws = wb['Sheet1'] + rows=ws.iter_rows() + S2=0 + iS2=0 + CP=0 + iCP=0 + PS=0 + iPS=0 + SE=0 + iSE=0 + SS=0 + iSS=0 + indexRow=0 + headRow=[] + for row in rows: + if (indexRow==0): + headRow=row + else: + for cell in row: + col=row.index(cell) + strHead=headRow[col].value.upper() + if '.S2.XML' in strHead: + try: + S2+=cell.value + iS2+=1 + except: + print "error" + + if '.CP.XML' in strHead: + try: + CP+=cell.value + iCP+=1 + except: + print "error" + if '.PS.XML' in strHead: + try: + PS+=cell.value + iPS+=1 + except: + print "error" + if '.SE.XML' in strHead: + try: + SE+=cell.value + iSE+=1 + except: + print "error" + if '.SS.XML' in strHead: + try: + SS+=cell.value + iSS+=1 + except: + print "error" + indexRow+=1 + S2Out=0 + CPOut=0 + PSOut=0 + SEOut=0 + SSOut=0 + if iS2>0: + S2Out= S2/iS2 + if iCP>0: + CPOut= CP/iCP + if iPS>0: + PSOut=PS/iPS + if SE>0: + SEOut=SE/iSE + if SS>0: + SSOut=SS/iSS + return S2Out,CPOut,PSOut,SEOut,SSOut + + def writeFinalXLS(self, rootDir,S2,CP,PS,SE,SS): + ''' + Writes the final.xlsx upon the inputs S2,CP,PS,SE,SS + ''' + wb=xlsxwriter.Workbook(rootDir+'\\final.xlsx') + ws=wb.add_worksheet() + ws.write(0, 0,"S2") + ws.write(0, 1,"CP") + ws.write(0, 2,"PS") + ws.write(0, 3,"SE") + ws.write(0, 4,"SS") + ws.write(1, 0,S2) + ws.write(1, 1,CP) + ws.write(1, 2,PS) + ws.write(1, 3,SE) + ws.write(1, 4,SS) + + wb.close() + + def __getPathStepsBack(self,f,stepsBack): + ''' + Private function: takes n steps back in the path from a file + ''' + fArray=f.split('\\') + path='' + for i in range(len(fArray)-stepsBack): + path+=fArray[i]+"/" + return path + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Result/ProcessGroundS2.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,155 @@ + + +''' +Created on 13/06/2014 + +@author: victor +''' + +from Process import PipelineAlignment +from Process import SymbolConversion +from Functions import MeasureFunctions + +class ProcessGroundS2: + + def getSimilarity(self,omrs,part): + ''' + main function to get the similarity vs the ground + + return: + result=percentage of similarity + errors= array with errors to write in xml + scoreWithErrors= score to write with colors + ''' + pa=PipelineAlignment() + mf=MeasureFunctions() + for omr in omrs: + try: + omr=mf.convertVoicesToChord(omr) + except: + pass + + omr_symbolsAlign=pa.alignGround(omrs,part) + + omr_ground=omr_symbolsAlign[0] + omr_part=omr_symbolsAlign[1] + + count=0 + symbolsLength=0 + Errors=[] + arrErrors=[] + for i in range(len(omr_ground)): + + sGround=omr_ground[i] + sOMR=omr_part[i] + if isinstance(sGround,list): + sGroundSimple=sGround[0] + else: + sGroundSimple=sGround + if isinstance(sOMR,list): + sOMRSimple=sOMR[0] + else: + sOMRSimple=sOMR + + #Removing grace notes + if(self.isGraceNote(sGround) or self.isGraceNote(sOMR)): + continue + + if(self.isBarline(sGroundSimple) or self.isBarline(sOMRSimple)): + continue + #Removing Time Signatures. PS introduce a lot extra time signatures +# if(self.isKeySignature(sGroundSimple) or self.isKeySignature(sOMRSimple)): +# continue + #Removing clef errors + if(self.isClef(sGroundSimple) or self.isClef(sOMRSimple)): + continue + if(self.isRest(sGroundSimple) or self.isRest(sOMRSimple)): + continue + #Removing extra rest due to voices +# if self.isRest(sOMRSimple): +# if sGroundSimple=="*": +# continue + + if (sGroundSimple==sOMRSimple): + if sGround[0]==sOMR[0] and sGround[1]==sOMR[1]:#not counting ties + #if sGround[0]==sOMR[0]: + count+=1 + else: + Errors.append([sGround,sOMR,i]) + arrErrors.append(i) + + else: + Errors.append([sGround,sOMR,i]) + arrErrors.append(i) + if sOMRSimple=="*": + try: + omr_part[i]=omr_ground[i] + omr_part[i][5]="#00ff00" #note missing + except: + print "error",omr_part[i] + elif sGroundSimple=="*": + try: + omr_part[i][5]="#0000ff" #extra note + except: + print "error",omr_part[i] + else: + try: + omr_part[i]=omr_ground[i] + omr_part[i][5]="#ff0000" #mistake in note + except: + print "error",omr_part[i] + + + symbolsLength+=1 + + result=(float(count)/symbolsLength)*100 + sc=SymbolConversion() + omr_part=sc.setVoices(omr_part) + scoreWithErrors=sc.convertM21(omr_part) + return result,Errors,scoreWithErrors + + def isGraceNote(self,s): + ''' + Returns true if the symbol is a grace note + ''' + if isinstance(s,list): + if s[0].find('N:')!=-1: + duration=s[1] + if float(duration)==0: + return True + + return False + + def isKeySignature(self,s): + ''' + Returns true if the symbol is a key signature + ''' + if s.find('KS:')!=-1: + return True + return False + + def isRest(self,s): + ''' + Returns true if the symbol is a rest + ''' + if s.find('R:')!=-1: + return True + return False + + def isBarline(self,s): + ''' + Returns true if the symbol is a barline + ''' + if s.find('!')!=-1: + return True + return False + + def isClef(self,s): + ''' + Returns true if the symbol is a clef + ''' + if s.find('CL:')!=-1: + return True + return False + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Result/__init__.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,2 @@ +from ExcellData import ExcellData +from ProcessGroundS2 import ProcessGroundS2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/__init__.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,15 @@ +# from Process import Clustering +# from Process import FullScoreAlignment +# from Process import PipelineAlignment + + +__all__ = [ + 'Preprocessing', + 'Process', + 'Functions', + 'Result', + 'Automatism', + 'Alignment' + ] + +# from MultipleOMR import * \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mainGDI.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,562 @@ +''' +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +GDI interface application with wxpython +The application can be run through command line (without windows interface) using +MainMultiOMR library +''' +import wx +import webbrowser +from Functions import AddingXMLSingleMeasures +from Automatism import BatchOMR +from MainMultiOMR import MainMultiOMR + +import modulefinder + +class MainWindow(wx.Frame): + ''' + Configuration of the main interface. + The application could be used without this interface, just with the classes of MainMultiOMR + ''' + + def __init__(self, parent, title): + ''' + init function + + ''' + self.runMainMenu(parent,title) + mf=MainMultiOMR() + mf._loadNWunsch() + + + def runMainMenu(self,parent,title): + ''' + Configure the main menu for the application + + ''' + wx.Frame.__init__(self, parent, title=title, size=(400,400)) + self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE) + self.CreateStatusBar() + + preprocessmenu=wx.Menu() + automatmenu=wx.Menu() + processmenu= wx.Menu() + resultmenu=wx.Menu() + utilsmenu=wx.Menu() + menu=wx.Menu() + + menuPDF2TIFF=preprocessmenu.Append(wx.ID_ANY, "& PDF to TIFF"," PDF to TIFF") + menuOssias=preprocessmenu.Append(wx.ID_ANY, "& Remove Ossias"," Remove Ossias") + + menuPSAuto=automatmenu.Append(wx.ID_ANY, "&PS"," PS") + menuSSAuto=automatmenu.Append(wx.ID_ANY, "&SS"," SS") + menuCPAuto=automatmenu.Append(wx.ID_ANY, "&CP"," CP") + menuSEAuto=automatmenu.Append(wx.ID_ANY, "&SE"," SE") + automatmenu.AppendSeparator() + menuAllAuto=automatmenu.Append(wx.ID_ANY, "&All"," All") + automatmenu.AppendSeparator() + menuCleanXML=automatmenu.Append(wx.ID_ANY, "&Clean XML"," Clean XML") + automatmenu.AppendSeparator() + menuSetupApp=automatmenu.Append(wx.ID_ANY, "&Setup Application"," Setup Application") + + menuOpenOneMovement = processmenu.Append(wx.ID_OPEN, "&Process one Movement"," Process one Movement") + menuOpenLoopBigData = processmenu.Append(wx.ID_ANY, "&Process Big Data"," Process big Data") + menuOpenLoopBigDataAdapt = processmenu.Append(wx.ID_ANY, "&Process Big Data Adapting OMRs"," Process big Data Adapting OMRs") + processmenu.AppendSeparator() + menuOpenCompleteProcess = processmenu.Append(wx.ID_ANY, "&Complete process"," Complete Process") + + menuOpenOneMovementGround=resultmenu.Append(wx.ID_ANY, "&Result one Movement"," Result one Movement") + menuOpenLoopBigDataGround = resultmenu.Append(wx.ID_ANY, "&Result Big Data"," Result Big Data") + processmenu.AppendSeparator() + menuFinalXLS = resultmenu.Append(wx.ID_ANY, "&Write final xls"," Write final xls") + + + menuWrongMeasures = utilsmenu.Append(wx.ID_ANY, "&View Wrong Measures"," Wrong measures") + utilsmenu.AppendSeparator() + menuJoinXMLs = utilsmenu.Append(wx.ID_ANY, "&Join XML"," Join XML") + utilsmenu.AppendSeparator() + menuViewM21 = utilsmenu.Append(wx.ID_ANY, "&View Through Music21"," View Music21") + utilsmenu.AppendSeparator() + menuConvertKrnToMusicXML = utilsmenu.Append(wx.ID_ANY, "&Krn to MusicXML"," Krn to MusicXML") + menuConvertMidiToMusicXML = utilsmenu.Append(wx.ID_ANY, "&Midi to MusicXML"," Midi to MusicXML") + menuConvertVoicesToChord = utilsmenu.Append(wx.ID_ANY, "&Voices to Chord"," Voices to Chord") + menuConvertBeamsToTriplets = utilsmenu.Append(wx.ID_ANY, "&Beams to Triplets"," Beams to Triplets") + menuRemovesEmptyVoices = utilsmenu.Append(wx.ID_ANY, "&Removes empty voices"," Removes empty voices") + menuRemovesGaps = utilsmenu.Append(wx.ID_ANY, "&Removes Gaps"," Removes Gaps") + utilsmenu.AppendSeparator() + menuAdaptOMRs = utilsmenu.Append(wx.ID_ANY, "&Adapt OMRs"," Adapt OMRs") + + menuAbout = menu.Append(wx.ID_ABOUT, "&About"," Information about this program") + menu.AppendSeparator() + menuDocumentation = menu.Append(wx.ID_ANY, "& Technical Documentation"," Technical Documentation") + menuUserManual = menu.Append(wx.ID_ANY, "& User Manual"," User Manual") + menu.AppendSeparator() + menuExit = menu.Append(wx.ID_EXIT,"E&xit"," Terminate the program") + + menuBar = wx.MenuBar() + menuBar.Append(preprocessmenu,"&Preprocessing") + menuBar.Append(automatmenu,"&Automatism") + menuBar.Append(processmenu,"&Process") + menuBar.Append(resultmenu,"&Results") + menuBar.Append(utilsmenu,"&Utils") + menuBar.Append(menu,"&Help") + + self.SetMenuBar(menuBar) + + self.Bind(wx.EVT_MENU, self.OnPDF2TIFF, menuPDF2TIFF) + self.Bind(wx.EVT_MENU, self.OnRemoveOssias, menuOssias) + + self.Bind(wx.EVT_MENU, self.OnViewPSAuto, menuPSAuto) + self.Bind(wx.EVT_MENU, self.OnViewSSAuto, menuSSAuto) + self.Bind(wx.EVT_MENU, self.OnViewCPAuto, menuCPAuto) + self.Bind(wx.EVT_MENU, self.OnViewSEAuto, menuSEAuto) + self.Bind(wx.EVT_MENU, self.OnViewAllAuto, menuAllAuto) + self.Bind(wx.EVT_MENU, self.OnViewCleanXML, menuCleanXML) + self.Bind(wx.EVT_MENU, self.OnViewSetupApp, menuSetupApp) + + self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout) + self.Bind(wx.EVT_MENU, self.OnDocumentation, menuDocumentation) + self.Bind(wx.EVT_MENU, self.OnUserManual, menuUserManual) + self.Bind(wx.EVT_MENU, self.OnOpenOneMovement, menuOpenOneMovement) + self.Bind(wx.EVT_MENU, self.OnOpenLoopBigData, menuOpenLoopBigData) + self.Bind(wx.EVT_MENU, self.OnOpenLoopBigDataAdapt, menuOpenLoopBigDataAdapt) + self.Bind(wx.EVT_MENU, self.OnOpenCompleteProcess, menuOpenCompleteProcess) + self.Bind(wx.EVT_MENU, self.OnExit, menuExit) + + self.Bind(wx.EVT_MENU, self.OnViewWrongMeasures, menuWrongMeasures) + self.Bind(wx.EVT_MENU, self.OnViewJoinXMLs, menuJoinXMLs) + self.Bind(wx.EVT_MENU, self.OnViewM21, menuViewM21) + self.Bind(wx.EVT_MENU, self.OnViewConvertKrnToMusicXML, menuConvertKrnToMusicXML) + self.Bind(wx.EVT_MENU, self.OnViewConvertMidiToMusicXML, menuConvertMidiToMusicXML) + self.Bind(wx.EVT_MENU, self.OnViewConvertVoicesToChord, menuConvertVoicesToChord) + self.Bind(wx.EVT_MENU, self.OnViewConvertBeamsToTriplets, menuConvertBeamsToTriplets) + self.Bind(wx.EVT_MENU, self.OnViewRemovesEmptyVoices, menuRemovesEmptyVoices) + self.Bind(wx.EVT_MENU, self.OnViewRemovesGaps, menuRemovesGaps) + self.Bind(wx.EVT_MENU, self.OnViewAdaptOMRs, menuAdaptOMRs) + + + + self.Bind(wx.EVT_MENU, self.OnOpenOneMovementGround, menuOpenOneMovementGround) + self.Bind(wx.EVT_MENU, self.OnOpenLoopBigDataGround, menuOpenLoopBigDataGround) + self.Bind(wx.EVT_MENU, self.OnOpenFinalXLS, menuFinalXLS) + + self.Show(True) + + + def OnPDF2TIFF(self,e): + dlg = wx.FileDialog(self, "Open .PDF file", "", "", + "PDF files (*.pdf)|*.pdf", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + mmo=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + filename = dlg.GetPath() + mmo.processPDF2TIFF(filename) + print "END" + dlg.Destroy() + + + def OnRemoveOssias(self,e): + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mmo=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + dirGeneral = dlg.GetPath() + mmo.processOssia(dirGeneral) + dlg.Destroy() + + + + def OnViewPSAuto(self,e): + ''' + ################ AUTOMATISM MENU ################## + Search all the images folder and convert .tif images to .XML + using PhotoScore (SIKULI) + ''' + batchOMR=BatchOMR() + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + batchOMR.processAllTiffFiles(dirname,"PS") + print "END" + dlg.Destroy() + + def OnViewSSAuto(self,e): + ''' + ################ AUTOMATISM MENU ################## + Search all the images folder and convert .tif images to .XML + using SmartScore (SIKULI) + ''' + batchOMR=BatchOMR() + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + batchOMR.processAllTiffFiles(dirname,"SS") + print "END" + dlg.Destroy() + + def OnViewCPAuto(self,e): + ''' + ################ AUTOMATISM MENU ################## + Search all the images folder and convert .tif images to .XML + using Capella (SIKULI) + ''' + batchOMR=BatchOMR() + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + batchOMR.processAllTiffFiles(dirname,"CP") + print "END" + dlg.Destroy() + + def OnViewSEAuto(self,e): + ''' + ################ AUTOMATISM MENU ################## + Search all the images folder and convert .tif images to .XML + using SharpEye (SIKULI) + ''' + batchOMR=BatchOMR() + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + batchOMR.processAllTiffFiles(dirname,"SE") + print "END" + dlg.Destroy() + + def OnViewAllAuto(self,e): + ''' + ################ AUTOMATISM MENU ################## + Search all the images folder and convert .tif images to .XML + using ALL the predefined OMR (SIKULI) + ''' + batchOMR=BatchOMR() + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + batchOMR.processAllTiffFiles(dirname,"ALL") + print "END" + dlg.Destroy() + + def OnViewCleanXML(self,e): + ''' + ################ AUTOMATISM MENU ################## + Utility for deleting all the files produced by the different OMR + (.XML files and .mro in case of SharpEye) + ''' + batchOMR=BatchOMR() + if wx.MessageBox("All XML Files will be deleted. Do you wish to continue?", "Please confirm", + wx.ICON_QUESTION | wx.YES_NO, self) == wx.NO: + return + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + batchOMR.cleanXMLFiles(dirname) + print "END" + dlg.Destroy() + + def OnViewSetupApp(self,e): + ''' + ################ AUTOMATISM MENU ################## + Utility for setup the 'Process' folder once the OMR files are finished + Two steps: + 1.- Copy the XML files + 2.- Take the .krn file and convert to ground.xml in the appropriate folder + ''' + batchOMR=BatchOMR() + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + print "-------COPY XML FILES----------" + batchOMR.setupApp(dirname) + print "-------CONVERT GROUND----------" + batchOMR.setGround(dirname) + ######## preparing files + + print "END" + dlg.Destroy() + + + + def OnOpenOneMovement(self,e): + ''' + ######################### PROCESS MENU ########################### + Processing just one movement + ''' + + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + dirGeneral = dlg.GetPath() + print "----START----:",dirGeneral + mf.processMovement(dirGeneral) + + dlg.Destroy() + + def OnOpenLoopBigData(self,e): + ''' + ######################### PROCESS MENU ########################### + BigData Process menu option + The program is waiting for files to process + This option can be executed in a different machine reading a common folder + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + rootDir = dlg.GetPath() + mf.runLoopBigData(rootDir,adaptOMRs=False) + dlg.Destroy() + + def OnOpenLoopBigDataAdapt(self,e): + ''' + ######################### PROCESS MENU ########################### + BigData Process menu option + The program is waiting for files to process + This option can be executed in a different machine reading a common folder + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + rootDir = dlg.GetPath() + mf.runLoopBigData(rootDir,adaptOMRs=True) + dlg.Destroy() + + + def OnOpenCompleteProcess(self,e): + ''' + ######################### PROCESS MENU ########################### + Run the complete process: + 1- Convert all .tif files to .XML (SIKULI) + 2- Processing all the files + 3- Get all the results + This option is thought in mind for running in a single machine + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + dirGeneral = dlg.GetPath() + print "----START----:",dirGeneral + mf.runCompleteProcess(dirGeneral) + + dlg.Destroy() + + + def OnOpenOneMovementGround(self,e): + ''' + ########################## RESULT MENU ################################# + Check each .xml file against 'ground.xml' and evaluate the differences. + The final result is written in the appropriated file + Example: + k428\Process\m1\parts\resultGeneral.xlsx + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + dirGeneral = dlg.GetPath() + mf.processMovementGround(dirGeneral) + dlg.Destroy() + + def OnOpenLoopBigDataGround(self,e): + ''' + ########################## RESULT MENU ################################# + BigData Result menu option + The program is waiting for files to get the result + This option can be executed in a different machine reading a common folder + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + rootDir = dlg.GetPath() + mf.runLoopBigDataGround(rootDir) + + dlg.Destroy() + + def OnOpenFinalXLS(self,e): + ''' + ########################## RESULT MENU ################################# + BigData Result menu option + The program is waiting for files to get the result + This option can be executed in a different machine reading a common folder + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + rootDir = dlg.GetPath() + mf.runFinalXLS(rootDir) + + dlg.Destroy() + + def OnViewWrongMeasures(self,e): + ''' + ########################## UTILS MENU ##################################### + Check the different errors in measures using + different procedures + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + print "---------S1------------" + mf.runViewWrongMeasures(dirname) + + dlg.Destroy() + + + def OnViewJoinXMLs(self,e): + ''' + ########################## UTILS MENU ##################################### + Add different measures + (under development) + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + addingXML=AddingXMLSingleMeasures() + addingXML.runViewJoinXML(dirname) + + dlg.Destroy() + + + + def OnViewM21(self,e): + ''' + ########################## UTILS MENU ##################################### + Show an .xml file processed by music21 + to check the differences and possible errors + ''' + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + mf.runViewM21(dirname) + dlg.Destroy() + + + + + def OnViewConvertKrnToMusicXML(self,e): + ''' + ########################## UTILS MENU ##################################### + convert one .krn file to .xml + ''' + dlg = wx.FileDialog(self, "Open .krn file", "", "", + "KRN files (*.krn)|*.krn", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + filename = dlg.GetPath() + mf.runConvertKrnToMusicXML(filename) + print "END" + dlg.Destroy() + + def OnViewConvertMidiToMusicXML(self,e): + ''' + ########################## UTILS MENU ##################################### + convert one .midi file to .xml + ''' + dlg = wx.FileDialog(self, "Open .mid file", "", "", + "MIDI files (*.mid)|*.mid", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + filename = dlg.GetPath() + mf.runConvertMidiToMusicXML(filename) + print "END" + dlg.Destroy() + + def OnViewConvertVoicesToChord(self,e): + ''' + ########################## UTILS MENU ##################################### + ''' + dlg = wx.FileDialog(self, "Open .mid file", "", "", + "xml files (*.xml)|*.xml", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + filename = dlg.GetPath() + mf.runConvertVoicesToChord(filename) + print "END" + dlg.Destroy() + + def OnViewConvertBeamsToTriplets(self,e): + ''' + ########################## UTILS MENU ##################################### + ''' + dlg = wx.FileDialog(self, "Open .mid file", "", "", + "xml files (*.xml)|*.xml", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + filename = dlg.GetPath() + mf.runConvertBeamsToTriplets(filename) + print "END" + dlg.Destroy() + + def OnViewRemovesEmptyVoices(self,e): + ''' + ########################## UTILS MENU ##################################### + ''' + dlg = wx.FileDialog(self, "Open .mid file", "", "", + "xml files (*.xml)|*.xml", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + filename = dlg.GetPath() + mf.runRemovesEmptyVoices(filename) + print "END" + dlg.Destroy() + def OnViewRemovesGaps(self,e): + ''' + ########################## UTILS MENU ##################################### + ''' + dlg = wx.FileDialog(self, "Open .mid file", "", "", + "xml files (*.xml)|*.xml", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + filename = dlg.GetPath() + mf.runRemovesGaps(filename) + print "END" + dlg.Destroy() + + def OnViewAdaptOMRs(self,e): + ''' + ########################## UTILS MENU ##################################### + ''' + + dlg = wx.DirDialog(None, "Choose a directory","",wx.DD_DEFAULT_STYLE) + mf=MainMultiOMR() + if dlg.ShowModal() == wx.ID_OK: + dirname = dlg.GetPath() + mf.runAdaptOMRs(dirname) + dlg.Destroy() + + def OnAbout(self,e): + ''' + ########################## MENU ##################################### + about menu option + ''' + dlg = wx.MessageDialog( self, "Big Data Project", "Big Data Project", wx.OK) + dlg.ShowModal() + dlg.Destroy() + + def OnDocumentation(self,e): + ''' + ########################## MENU ##################################### + open documentation web + ''' + webbrowser.open_new("..\\Documentation\\html\\index.html") + def OnUserManual(self,e): + ''' + ########################## MENU ##################################### + open user manual + ''' + webbrowser.open_new("..\\Documentation\\Manual.pdf") + def OnExit(self,e): + ''' + ########################## MENU ##################################### + exit menu option + ''' + self.Close(True) + + + + +app = wx.App(False) +frame = MainWindow(None, "Big Data Process") +app.MainLoop() \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/setup.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,17 @@ +from distutils.core import setup +import sys +import py2exe +import numpy + + + +from glob import glob +data_files = [("Microsoft.VC90.CRT", glob(r'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT\*.*'))] +sys.path.append("C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\redist\\x86\\Microsoft.VC90.CRT") + +setup( + data_files=data_files, + + console=['mainGDI.py'], + + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/CP.sikuli/CP.html Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,112 @@ + +<html> + <head> + <style type="text/css"> + .sikuli-code { + font-size: 20px; + font-family: "Osaka-mono", Monospace; + line-height: 1.5em; + display:table-cell; + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + width: 99%; /* remove horizontal scroll-bar when viewing in IE7 */ + } + .sikuli-code img { + vertical-align: middle; + margin: 2px; + border: 1px solid #ccc; + padding: 2px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -moz-box-shadow: 1px 1px 1px gray; + -webkit-box-shadow: 1px 1px 2px gray; + } + .kw { + color: blue; + } + .skw { + color: rgb(63, 127, 127); + } + + .str { + color: rgb(128, 0, 0); + } + + .dig { + color: rgb(128, 64, 0); + } + + .cmt { + color: rgb(200, 0, 200); + } + + h2 { + display: inline; + font-weight: normal; + } + + .info { + border-bottom: 1px solid #ddd; + padding-bottom: 5px; + margin-bottom: 20px; + display: none; + } + + a { + color: #9D2900; + } + + body { + font-family: "Trebuchet MS", Arial, Sans-Serif; + } + + </style> + </head> +<body> +<div class="info"> +<h2>CP.sikuli\CP.sikuli</h2> <a href="CP.sikuli\CP.zip">(Download this script)</a> +</div> +<pre class="sikuli-code"> +params = sys.argv[<span class="dig">1</span>:] +path=params[<span class="dig">0</span>] +strIMGs=<span class="str">""</span> + +<span class="skw">click</span>(<img src="1415710175004.png" />) +<span class="skw">wait</span>(<img src="1415710207538.png" />,FOREVER) +<span class="skw">click</span>(<img src="1415710242258.png" />) +<span class="skw">wait</span>(<img src="1415710292754.png" />,FOREVER) +<span class="skw">type</span>(Key.BACKSPACE) + +<span class="skw">click</span>(<img src="1415791421283.png" />) +strPath=path.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(strPath[:-<span class="dig">1</span>]) +<span class="skw">click</span>(<img src="1415791723329.png" />) +<span class="skw">sleep</span>(<span class="dig">1</span>) +<span class="skw">type</span>(Key.BACKSPACE) +<span class="kw">for</span> i <span class="kw">in</span> range(<span class="dig">1</span>,len(params)): + strIMGs=strIMGs+<span class="str">" \""</span>+params[i]+<span class="str">"\""</span> +strInput=strIMGs +strInput=strInput.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(strInput) +<span class="skw">click</span>(<img src="1415791723329.png" />) +<span class="skw">click</span>(<img src="1415710897800.png" />) +<span class="skw">wait</span>(Pattern(<img src="1415711761225.png" />).similar(<span class="dig">0.90</span>),FOREVER) +<span class="skw">click</span>(<img src="1415711065949.png" />) +<span class="skw">wait</span>(<img src="1415711940063.png" />,FOREVER) +<span class="skw">wait</span>(<span class="dig">1</span>) +<span class="skw">type</span>(Key.BACKSPACE) +<span class="skw">click</span>(<img src="1415791774505.png" />) +strOUT=path+<span class="str">"CP.xml"</span> +strOUT=strOUT.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(strOUT) +<span class="skw">click</span>(<img src="1415791801451.png" />) +<span class="kw">if</span> exists(<img src="1415700984115.png" />): + <span class="skw">click</span>(<img src="1415700984115.png" />) +<span class="kw">if</span> exists(<img src="cerrar.png" />): + <span class="skw">click</span>(<img src="cerrar.png" />) +</pre> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/CP.sikuli/CP.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,37 @@ +params = sys.argv[1:] +path=params[0] +strIMGs="" + +click("1415710175004.png") +wait("1415710207538.png",FOREVER) +click("1415710242258.png") +wait("1415710292754.png",FOREVER) +type(Key.BACKSPACE) + +click("1415791421283.png") +strPath=path.replace("/","\\") +paste(strPath[:-1]) +click("1415791723329.png") +sleep(1) +type(Key.BACKSPACE) +for i in range(1,len(params)): + strIMGs=strIMGs+" \""+params[i]+"\"" +strInput=strIMGs +strInput=strInput.replace("/","\\") +paste(strInput) +click("1415791723329.png") +click("1415710897800.png") +wait(Pattern("1415711761225.png").similar(0.90),FOREVER) +click("1415711065949.png") +wait("1415711940063.png",FOREVER) +wait(1) +type(Key.BACKSPACE) +click("1415791774505.png") +strOUT=path+"CP.xml" +strOUT=strOUT.replace("/","\\") +paste(strOUT) +click("1415791801451.png") +if exists("1415700984115.png"): + click("1415700984115.png") +if exists("cerrar.png"): + click("cerrar.png") \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/PS.sikuli/PS.html Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,138 @@ + +<html> + <head> + <style type="text/css"> + .sikuli-code { + font-size: 20px; + font-family: "Osaka-mono", Monospace; + line-height: 1.5em; + display:table-cell; + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + width: 99%; /* remove horizontal scroll-bar when viewing in IE7 */ + } + .sikuli-code img { + vertical-align: middle; + margin: 2px; + border: 1px solid #ccc; + padding: 2px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -moz-box-shadow: 1px 1px 1px gray; + -webkit-box-shadow: 1px 1px 2px gray; + } + .kw { + color: blue; + } + .skw { + color: rgb(63, 127, 127); + } + + .str { + color: rgb(128, 0, 0); + } + + .dig { + color: rgb(128, 64, 0); + } + + .cmt { + color: rgb(200, 0, 200); + } + + h2 { + display: inline; + font-weight: normal; + } + + .info { + border-bottom: 1px solid #ddd; + padding-bottom: 5px; + margin-bottom: 20px; + display: none; + } + + a { + color: #9D2900; + } + + body { + font-family: "Trebuchet MS", Arial, Sans-Serif; + } + + </style> + </head> +<body> +<div class="info"> +<h2>PS.sikuli\PS.sikuli</h2> <a href="PS.sikuli\PS.zip">(Download this script)</a> +</div> +<pre class="sikuli-code"> +params = sys.argv[<span class="dig">1</span>:] +path=params[<span class="dig">0</span>] +strIMGs=<span class="str">""</span> + +<span class="skw">click</span>(<img src="1415626157985.png" />) +<span class="skw">wait</span>(<img src="1415626436439.png" />,FOREVER) +<span class="skw">type</span>(<span class="str">"o"</span>, KeyModifier.CTRL) +<span class="skw">wait</span>(<img src="1415791940762.png" />,FOREVER) +<span class="cmt">#click("1415882981586.png") +</span><span class="skw">click</span>(Pattern(<img src="1415963511508.png" />).targetOffset(<span class="dig">45</span>,<span class="dig">14</span>)) +<span class="skw">type</span>(Key.BACKSPACE) +paste(path) +<span class="skw">click</span>(<img src="2014-11-13_12-53-25.png" />) +<span class="skw">click</span>(<img src="1415791956757.png" />) + +<span class="kw">for</span> i <span class="kw">in</span> range(<span class="dig">1</span>,len(params)): + strIMGs=strIMGs+<span class="str">" \""</span>+params[i]+<span class="str">"\""</span> +strInput=strIMGs +strInput=strInput.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) + +paste(strInput) +<span class="skw">click</span>(<img src="1415791980822.png" />) + +<span class="skw">wait</span>(<img src="1415628223695.png" />,FOREVER) + +<span class="kw">if</span>(len(params)==<span class="dig">3</span>): + <span class="skw">wait</span>(Pattern(<img src="1415785439675.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">4</span>): + <span class="skw">wait</span>(Pattern(<img src="1415785928359.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">5</span>): + <span class="skw">wait</span>(Pattern(<img src="1415786066894.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">6</span>): + <span class="skw">wait</span>(Pattern(<img src="1415876625654.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">7</span>): + <span class="skw">wait</span>(Pattern(<img src="1415876704875.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">8</span>): + <span class="skw">wait</span>(Pattern(<img src="1415876822838.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">9</span>): + <span class="skw">wait</span>(Pattern(<img src="1415876912038.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">10</span>): + <span class="skw">wait</span>(Pattern(<img src="1416238736460.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">11</span>): + <span class="skw">wait</span>(Pattern(<img src="1416238784250.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">12</span>): + <span class="skw">wait</span>(Pattern(<img src="1416239106139.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">13</span>): + <span class="skw">wait</span>(Pattern(<img src="1416239184735.png" />).exact(),FOREVER) +<span class="kw">if</span>(len(params)==<span class="dig">14</span>): + <span class="skw">wait</span>(Pattern(<img src="1417434097757.png" />).exact(),FOREVER) + + +<span class="skw">click</span>(<img src="1415628257531.png" />) +<span class="skw">wait</span>(<img src="1415792044614.png" />,FOREVER) +<span class="skw">type</span>(Key.BACKSPACE) +<span class="skw">click</span>(<img src="1415792076797.png" />) +strOUT=path+<span class="str">"PS.xml"</span> +strOUT=strOUT.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(strOUT) +<span class="skw">click</span>(<img src="1415792095379.png" />) +<span class="kw">if</span> exists(<img src="1415700984115.png" />): + <span class="skw">click</span>(<img src="1415700984115.png" />) +<span class="kw">if</span> exists(<img src="cerrar.png" />): + <span class="skw">click</span>(<img src="cerrar.png" />) +</pre> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/PS.sikuli/PS.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,65 @@ +params = sys.argv[1:] +path=params[0] +strIMGs="" + +click("1415626157985.png") +wait("1415626436439.png",FOREVER) +type("o", KeyModifier.CTRL) +wait("1415791940762.png",FOREVER) +#click("1415882981586.png") +click(Pattern("1415963511508.png").targetOffset(45,14)) +type(Key.BACKSPACE) +paste(path) +click("2014-11-13_12-53-25.png") +click("1415791956757.png") + +for i in range(1,len(params)): + strIMGs=strIMGs+" \""+params[i]+"\"" +strInput=strIMGs +strInput=strInput.replace("/","\\") + +paste(strInput) +click("1415791980822.png") + +wait("1415628223695.png",FOREVER) + +if(len(params)==3): + wait(Pattern("1415785439675.png").exact(),FOREVER) +if(len(params)==4): + wait(Pattern("1415785928359.png").exact(),FOREVER) +if(len(params)==5): + wait(Pattern("1415786066894.png").exact(),FOREVER) +if(len(params)==6): + wait(Pattern("1415876625654.png").exact(),FOREVER) +if(len(params)==7): + wait(Pattern("1415876704875.png").exact(),FOREVER) +if(len(params)==8): + wait(Pattern("1415876822838.png").exact(),FOREVER) +if(len(params)==9): + wait(Pattern("1415876912038.png").exact(),FOREVER) +if(len(params)==10): + wait(Pattern("1416238736460.png").exact(),FOREVER) +if(len(params)==11): + wait(Pattern("1416238784250.png").exact(),FOREVER) +if(len(params)==12): + wait(Pattern("1416239106139.png").exact(),FOREVER) +if(len(params)==13): + wait(Pattern("1416239184735.png").exact(),FOREVER) +if(len(params)==14): + wait(Pattern("1417434097757.png").exact(),FOREVER) + + +click("1415628257531.png") +wait("1415792044614.png",FOREVER) +type(Key.BACKSPACE) +click("1415792076797.png") +strOUT=path+"PS.xml" +strOUT=strOUT.replace("/","\\") +paste(strOUT) +click("1415792095379.png") +if exists("1415700984115.png"): + click("1415700984115.png") +if exists("cerrar.png"): + click("cerrar.png") + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/SE.sikuli/SE.html Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,139 @@ + +<html> + <head> + <style type="text/css"> + .sikuli-code { + font-size: 20px; + font-family: "Osaka-mono", Monospace; + line-height: 1.5em; + display:table-cell; + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + width: 99%; /* remove horizontal scroll-bar when viewing in IE7 */ + } + .sikuli-code img { + vertical-align: middle; + margin: 2px; + border: 1px solid #ccc; + padding: 2px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -moz-box-shadow: 1px 1px 1px gray; + -webkit-box-shadow: 1px 1px 2px gray; + } + .kw { + color: blue; + } + .skw { + color: rgb(63, 127, 127); + } + + .str { + color: rgb(128, 0, 0); + } + + .dig { + color: rgb(128, 64, 0); + } + + .cmt { + color: rgb(200, 0, 200); + } + + h2 { + display: inline; + font-weight: normal; + } + + .info { + border-bottom: 1px solid #ddd; + padding-bottom: 5px; + margin-bottom: 20px; + display: none; + } + + a { + color: #9D2900; + } + + body { + font-family: "Trebuchet MS", Arial, Sans-Serif; + } + + </style> + </head> +<body> +<div class="info"> +<h2>SE.sikuli\SE.sikuli</h2> <a href="SE.sikuli\SE.zip">(Download this script)</a> +</div> +<pre class="sikuli-code"> +params = sys.argv[<span class="dig">1</span>:] +path=params[<span class="dig">0</span>] +strIMGs=<span class="str">""</span> + +<span class="skw">click</span>(<img src="1415716688669.png" />) +<span class="skw">wait</span>(<img src="1415716721174.png" />,FOREVER) +<span class="skw">click</span>(<img src="1415716758693.png" />) +<span class="skw">click</span>(<img src="DropDown.png" />) +<span class="skw">wait</span>(<img src="1415716942199.png" />,FOREVER) +<span class="skw">click</span>(<img src="1415716964607.png" />) +<span class="skw">wait</span>(<img src="1415792167505.png" />,FOREVER) +<span class="skw">click</span>(Pattern(<img src="1415963853362.png" />).targetOffset(<span class="dig">45</span>,<span class="dig">15</span>)) +<span class="skw">type</span>(Key.BACKSPACE) +paste(path) +<span class="skw">click</span>(<img src="2014-11-13_13-34-35.png" />) + + +<span class="skw">click</span>(<img src="1415792179506.png" />) + +<span class="kw">for</span> i <span class="kw">in</span> range(<span class="dig">1</span>,len(params)): + strIMGs=strIMGs+<span class="str">" \""</span>+params[i]+<span class="str">"\""</span> +strInput=strIMGs +strInput=strInput.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) + +paste(strInput) +<span class="skw">click</span>(<img src="1415792207078.png" />) +<span class="skw">rightClick</span>(<img src="1415717208007.png" />) +<span class="skw">click</span>(<img src="2014-11-12_11-58-32.png" />) + +<span class="skw">sleep</span>(<span class="dig">1</span>) + +<span class="skw">type</span>(Key.BACKSPACE) +<span class="skw">click</span>(<img src="1415717913108.png" />) +paste(path[:-<span class="dig">1</span>]) +<span class="skw">click</span>(<img src="1415717515734.png" />) +<span class="skw">wait</span>(<img src="1415718431424.png" />,FOREVER) +<span class="skw">click</span>(<img src="1415792424959.png" />) +<span class="skw">click</span>(<img src="1415718524045.png" />) +<span class="skw">wait</span>(<img src="1415792444947.png" />,FOREVER) +<span class="skw">type</span>(Key.BACKSPACE) +<span class="skw">click</span>(<img src="1415792490785.png" />) +newPath=path.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(newPath+<span class="str">"AllPages.mro"</span>) +<span class="skw">click</span>(<img src="1415792510149.png" />) +<span class="kw">if</span> exists(<img src="1417614329432.png" />): + <span class="skw">click</span>(<img src="1417614361971.png" />) +<span class="skw">click</span>(Pattern(<img src="1415718695577.png" />).exact()) + +<span class="skw">wait</span>(<img src="1415792536736.png" />,FOREVER) +<span class="skw">type</span>(Key.BACKSPACE) +<span class="skw">click</span>(<img src="1415792587415.png" />) + +strOUT=path+<span class="str">"SE.xml"</span> +strOUT=strOUT.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(strOUT) + +<span class="skw">click</span>(<img src="1415792640839.png" />) +<span class="kw">if</span> exists(<img src="1415792786165.png" />): + <span class="skw">click</span>(<img src="1415792803049.png" />) + +<span class="kw">if</span> exists(<img src="1415700984115.png" />): + <span class="skw">click</span>(<img src="1415700984115.png" />) +<span class="kw">if</span> exists(<img src="cerrar.png" />): + <span class="skw">click</span>(<img src="cerrar.png" />) +</pre> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/SE.sikuli/SE.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,71 @@ +params = sys.argv[1:] +path=params[0] +strIMGs="" + +click("1415716688669.png") +wait("1415716721174.png",FOREVER) +click("1415716758693.png") +click("DropDown.png") +wait("1415716942199.png",FOREVER) +click("1415716964607.png") +wait("1415792167505.png",FOREVER) +click(Pattern("1415963853362.png").targetOffset(45,15)) +type(Key.BACKSPACE) +paste(path) +click("2014-11-13_13-34-35.png") + + +click("1415792179506.png") + +for i in range(1,len(params)): + strIMGs=strIMGs+" \""+params[i]+"\"" +strInput=strIMGs +strInput=strInput.replace("/","\\") + +paste(strInput) +click("1415792207078.png") +rightClick("1415717208007.png") +click("2014-11-12_11-58-32.png") + +sleep(1) + +type(Key.BACKSPACE) +click("1415717913108.png") +paste(path[:-1]) +click("1415717515734.png") +wait("1415718431424.png",FOREVER) +click("1415792424959.png") +click("1415718524045.png") +wait("1415792444947.png",FOREVER) +type(Key.BACKSPACE) +click("1415792490785.png") +newPath=path.replace("/","\\") +paste(newPath+"AllPages.mro") +click("1415792510149.png") +if exists("1417614329432.png"): + click("1417614361971.png") +click(Pattern("1415718695577.png").exact()) + +wait("1415792536736.png",FOREVER) +type(Key.BACKSPACE) +click("1415792587415.png") + +strOUT=path+"SE.xml" +strOUT=strOUT.replace("/","\\") +paste(strOUT) + +click("1415792640839.png") +if exists("1415792786165.png"): + click("1415792803049.png") + +if exists("1415700984115.png"): + click("1415700984115.png") +if exists("cerrar.png"): + click("cerrar.png") + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/SS.sikuli/SS.html Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,126 @@ + +<html> + <head> + <style type="text/css"> + .sikuli-code { + font-size: 20px; + font-family: "Osaka-mono", Monospace; + line-height: 1.5em; + display:table-cell; + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + width: 99%; /* remove horizontal scroll-bar when viewing in IE7 */ + } + .sikuli-code img { + vertical-align: middle; + margin: 2px; + border: 1px solid #ccc; + padding: 2px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -moz-box-shadow: 1px 1px 1px gray; + -webkit-box-shadow: 1px 1px 2px gray; + } + .kw { + color: blue; + } + .skw { + color: rgb(63, 127, 127); + } + + .str { + color: rgb(128, 0, 0); + } + + .dig { + color: rgb(128, 64, 0); + } + + .cmt { + color: rgb(200, 0, 200); + } + + h2 { + display: inline; + font-weight: normal; + } + + .info { + border-bottom: 1px solid #ddd; + padding-bottom: 5px; + margin-bottom: 20px; + display: none; + } + + a { + color: #9D2900; + } + + body { + font-family: "Trebuchet MS", Arial, Sans-Serif; + } + + </style> + </head> +<body> +<div class="info"> +<h2>SS.sikuli\SS.sikuli</h2> <a href="SS.sikuli\SS.zip">(Download this script)</a> +</div> +<pre class="sikuli-code"> +params = sys.argv[<span class="dig">1</span>:] +path=params[<span class="dig">0</span>] +strIMGs=<span class="str">""</span> + +<span class="skw">click</span>(<img src="1415701611441.png" />) +<span class="skw">wait</span>(<img src="1415701865784.png" />,FOREVER) +<span class="skw">click</span>(<img src="1415701911562.png" />) +<span class="skw">wait</span>(<img src="1415701967254.png" />,FOREVER) +<span class="skw">click</span>(<img src="1415702019016.png" />) +<span class="skw">wait</span>(<img src="1415792857317.png" />,FOREVER) + +<span class="skw">click</span>(Pattern(<img src="1415963913666.png" />).targetOffset(<span class="dig">47</span>,<span class="dig">13</span>)) +<span class="cmt">#click("1415885604725.png") +</span><span class="skw">type</span>(Key.BACKSPACE) +paste(path) +<span class="skw">click</span>(<img src="2014-11-13_13-34-35.png" />) + + +<span class="skw">click</span>(<img src="1415792869010.png" />) + +<span class="kw">for</span> i <span class="kw">in</span> range(<span class="dig">1</span>,len(params)): + strIMGs=strIMGs+<span class="str">" \""</span>+params[i]+<span class="str">"\""</span> +strInput=strIMGs +strInput=strInput.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(strInput) +<span class="skw">click</span>(<img src="1415792905305.png" />) +<span class="skw">click</span>(<img src="1415702225757.png" />) +<span class="skw">wait</span>(<img src="1415792946298.png" />,FOREVER) +<span class="skw">wait</span>(<span class="dig">1</span>) +<span class="skw">type</span>(Key.BACKSPACE) +<span class="skw">click</span>(<img src="1415792965001.png" />) +strOUT=path+<span class="str">"SS.xml"</span> +strOUT=strOUT.replace(<span class="str">"/"</span>,<span class="str">"\\"</span>) +paste(strOUT) +<span class="skw">click</span>(<img src="1415798023757.png" />) +<span class="skw">click</span>(<img src="select.png" />) +<span class="skw">click</span>(<img src="1415793010197.png" />) +<span class="skw">wait</span>(<span class="dig">1</span>) +<span class="kw">if</span> exists(<img src="1416922791607.png" />): + <span class="skw">wait</span>(<span class="dig">1</span>) +<span class="kw">if</span> exists(<img src="1416922791607.png" />): + <span class="skw">wait</span>(<span class="dig">1</span>) +<span class="kw">if</span> exists(<img src="1416922791607.png" />): + <span class="skw">wait</span>(<span class="dig">1</span>) + +<span class="kw">if</span> exists(<img src="1415700984115.png" />): + <span class="skw">click</span>(<img src="1415700984115.png" />) +<span class="kw">if</span> exists(<img src="cerrar.png" />): + <span class="skw">click</span>(<img src="cerrar.png" />) +<span class="kw">if</span> exists(<img src="1415798271832.png" />): + <span class="skw">click</span>(<img src="1415706040951.png" />) +</pre> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sikuli/SS.sikuli/SS.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,57 @@ +params = sys.argv[1:] +path=params[0] +strIMGs="" + +click("1415701611441.png") +wait("1415701865784.png",FOREVER) +click("1415701911562.png") +wait("1415701967254.png",FOREVER) +click("1415702019016.png") +wait("1415792857317.png",FOREVER) + +click(Pattern("1415963913666.png").targetOffset(47,13)) +#click("1415885604725.png") +type(Key.BACKSPACE) +paste(path) +click("2014-11-13_13-34-35.png") + + +click("1415792869010.png") + +for i in range(1,len(params)): + strIMGs=strIMGs+" \""+params[i]+"\"" +strInput=strIMGs +strInput=strInput.replace("/","\\") +paste(strInput) +click("1415792905305.png") +click("1415702225757.png") +wait("1415792946298.png",FOREVER) +wait(1) +type(Key.BACKSPACE) +click("1415792965001.png") +strOUT=path+"SS.xml" +strOUT=strOUT.replace("/","\\") +paste(strOUT) +click("1415798023757.png") +click("select.png") +click("1415793010197.png") +wait(1) +if exists("1416922791607.png"): + wait(1) +if exists("1416922791607.png"): + wait(1) +if exists("1416922791607.png"): + wait(1) + +if exists("1415700984115.png"): + click("1415700984115.png") +if exists("cerrar.png"): + click("cerrar.png") +if exists("1415798271832.png"): + click("1415706040951.png") + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test.py Mon May 04 22:56:18 2015 +0200 @@ -0,0 +1,29 @@ +''' +@organization: Lancaster University & University of Leeds +@version: 1.0 +Created on 11/12/2014 + +@author: Victor Padilla +@contact: v.padilla@lancaster.ac.uk + +test file for checking +''' + +from MultipleOMR.Alignment import FastAlignmentArrays +from MultipleOMR.Alignment import NWunsch + +a=["foo00","abc","123"] +b=["foo000","abc","1234"] + +# a=['TS:3/8', 'CL:G', 'KS:0', u'N:C5_0.125', '!', u'N:B4_1.0', u'N:A4_0.5', '!', 'R:1.5', '!', 'R:0.5', u'N:F5_0.25', u'N:D5_0.25', u'N:E5_0.25', u'N:F5_0.25', '!', u'N:D5_0.25', u'N:E5_0.25', u'N:F5_0.5', u'N:G5_0.5', '!', u'N:E5_0.5', '!', 'KS:-3', 'R:0.5', u'N:E-5_0.25', u'N:C5_0.25', u'N:D5_0.25', u'N:E-5_0.25', '!', u'N:C5_0.25', u'N:D5_0.25', u'N:E-5_0.5', u'N:F5_0.5', '!', u'N:D5_0.5', u'N:B-4_0.5', u'N:B-5_0.5', '!', u'N:B-5_0.5', u'N:G5_0.5', u'N:F5_0.25', '!', 'R:1.5', '!', u'N:B-4_1.0', '!', 'R:1.0', 'KS:0', u'N:E3_0.25', u'N:C3_0.25', '!', 'CL:F', u'N:D3_0.5', 'R:0.5', 'R:0.5', '!', u'N:D3_0.5', u'N:D4_0.5', u'N:D4_0.5', '!', 'R:0.25', u'N:B3_0.5', u'N:A3_0.25', u'N:G3_0.25', u'N:F3_0.25', '!', u'N:E3_0.25', '!', 'R:1.5', '!', 'KS:-3', u'N:B-4_1.0', u'N:C5_0.25', u'N:A4_0.25', '!', 'CL:G', u'C:[:A-4_0.5[:A-5_0.5', u'C:[:G4_0.5[:G5_0.5', u'C:[:B-4_0.5[:B-5_0.5', '!', u'N:D5_1.0', u'N:G5_2.0', '!', u'N:E-5_0.25', u'N:C5_0.25', u'C:[:A-4_0.5[:A-5_0.5', u'C:[:G4_0.5[:G5_0.5', '!', u'C:[:B-4_0.5[:B-5_0.5', '!', u'N:D5_1.0', u'N:G5_2.0', '!', u'N:E-5_0.25', u'N:C5_0.25', u'N:B-4_0.25', u'N:D5_0.25', u'N:F5_0.25', u'N:B-5_0.25', '!', u'N:F5_0.25', u'N:D5_0.25', u'N:E-5_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', '!', u'N:D5_0.25', u'N:F4_0.25', u'N:B-4_0.25', u'N:F4_0.25', u'N:D4_0.25', u'N:E-4_0.25', '!', u'N:C4_0.25', u'N:A3_0.25', u'N:B-3_0.5', 'R:0.5', '!', u'C:[:F3_0.5[:B-3_0.5', u'C:[:F3_0.5[:B-3_0.5', 'R:0.5', '!', 'R:0.5', '!', 'R:0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', '!', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:B-5_1.0', '!', u'N:D5_0.5', u'N:E-5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', '!', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:B-5_1.0', '!', u'N:E5_0.5', '!', u'N:F5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', '!', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:B-5_1.0', '!', u'N:F5_0.5', 'R:0.5', u'N:G-5_0.5', '!', u'N:E-5_0.5', 'R:0.5', u'N:E-5_0.5', '!', u'N:A4_0.5', 'R:0.5', u'N:B-4_0.5', '!', u'N:D5_0.5', u'N:F5_0.5', u'N:A5_0.5', '!', u'N:B-5_0.5', '!', u'N:B-4_0.5', u'C:[:D4_0.5[:A-4_0.5', '!', u'C:[:D4_0.5[:A-4_0.5', 'R:0.5', 'R:0.5', '!', 'R:0.5', 'R:0.5', u'N:B-5_0.25', u'N:G5_0.5', u'N:C6_0.25', u'N:B-5_0.25', u'N:F5_0.5', u'N:A-5_0.25', '!', u'N:B-5_0.25', u'N:E-5_0.5', u'N:A-5_0.25', u'N:G5_0.25', u'N:D5_0.5', u'N:A-5_0.25', u'N:G5_0.25', u'N:F5_0.25', '!', u'N:G5_0.25', u'N:C5_0.5', u'N:F5_0.25', u'N:E-5_0.25', u'N:B-4_0.5', u'N:F5_0.25', u'N:E-5_0.25', u'N:D5_0.25', '!', u'N:E-5_0.25', u'N:A-4_0.5', u'N:D5_0.25', u'N:C5_0.25', u'N:G4_0.5', u'N:D5_0.25', u'N:C5_0.25', u'N:B-4_0.5', '!', u'N:B-4_1.5', u'N:F4_0.5', u'N:E-4_0.5', u'N:D4_0.5', '!', u'C:[:D4_0.5[:B-4_0.5', u'C:[:E-4_0.5[:C5_0.5', u'C:[:F4_0.5[:D5_0.5', '!', u'N:E-5_0.25', u'N:G4_1.0', u'N:G5_0.375', u'N:F5_0.25', u'N:E-5_0.25', u'N:D5_0.25', u'N:E-5_0.25', '!', u'N:G4_1.0', u'C:[:A-4_0.5[:C5_0.5', u'N:D5_0.25', u'N:C5_0.25', u'N:B-4_1.0', '!', u'N:A-4_0.25', u'N:F4_0.5', u'N:G4_0.125', u'N:A-4_0.125', u'N:G4_0.5', u'N:D5_0.5', '!', u'N:E-5_0.5', '!', 'R:0.5', u'N:B-5_0.5', u'N:G5_0.5', '!', 'R:0.25', u'N:F5_0.25', u'N:G5_0.25', u'N:A-5_0.25', u'N:B-5_0.25', u'N:C6_0.25', '!', u'N:C6_0.25', u'N:B-5_0.25', u'N:A-5_0.25', u'N:G5_0.25', u'N:F5_0.25', u'N:D5_0.25', '!', u'N:E-5_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:E-4_0.25', '!', u'N:D4_0.25', u'N:F4_0.25', u'N:A-4_0.25', u'N:G4_0.25', u'N:B-4_0.25', u'N:G4_0.25', '!', u'N:E-5_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:A-4_0.25', u'N:F4_0.25', u'N:D4_0.25', '!', u'N:E-4_0.5', 'R:0.5', u'C:[:B-3_0.5[:E-4_0.5', '!', u'C:[:B-3_0.5[:E-4_0.5', 'R:0.5', 'R:0.5', '!', u'N:E-5_0.5', u'N:E-5_0.125', u'N:F5_0.125', u'N:E-5_0.125', u'N:D-5_0.125', u'N:C5_0.5', '!', 'R:0.5', u'N:A-5_0.5', u'N:A-5_0.5', '!', u'N:G5_0.5', u'N:G5_0.125', u'N:A-5_0.125', u'N:B-5_0.125', u'N:A-5_0.125', u'N:G5_0.5', '!', 'R:0.5', u'N:D-6_0.5', u'N:D-6_0.5', '!', u'N:C6_0.5', u'N:C6_0.125', u'N:C6_1.0', u'N:D6_0.125', u'N:E-6_0.125', u'N:D6_0.125', u'N:C6_0.5', '!', 'R:0.5', 'KS:0', '!', u'N:F5_0.5', 'R:1.0', '!', u'N:F5_0.5', u'N:F5_0.25', '!', 'R:1.5', '!', 'R:1.5', '!', u'N:G4_0.5', 'KS:-3', 'R:0.5', u'N:G5_0.5', '!', u'N:F5_0.5', 'KS:0', 'R:0.5', u'N:A5_0.5', '!', 'R:0.5', u'N:C6_0.5', u'N:B-5_0.125', u'N:A5_0.125', u'N:G5_0.125', u'N:F5_0.125', '!', u'N:E5_1.0', u'N:D5_0.5', '!', 'R:4.0', '!', 'R:0.5', 'R:0.5', u'N:B5_0.25', u'N:G5_0.25', u'N:A5_0.25', u'N:B5_0.25', '!', 'R:0.5', u'N:G5_0.25', u'N:A5_0.25', '!', 'KS:-3', u'N:B-5_0.5', u'N:C6_0.5', u'N:A-5_0.5', '!', 'R:0.5', u'N:A-5_0.25', u'N:F5_0.25', u'N:G5_0.25', u'N:A-5_0.25', '!', u'N:F5_0.25', u'N:G5_0.25', u'N:A-5_0.5', u'N:B-5_0.5', '!', u'N:G5_0.5', u'N:E-5_0.5', u'N:E-6_0.5', '!', u'N:E-6_0.5', u'N:C6_0.5', '!', 'R:1.5', '!', u'N:E-5_1.0', u'N:A-5_2.0', '!', u'N:F5_0.25', u'N:D5_0.25', u'N:E-5_0.5', 'R:0.5', '!', 'R:0.5', u'N:B-4_0.5', u'N:G5_0.25', u'N:D5_0.25', '!', u'N:E-5_0.25', u'N:G5_0.25', u'N:D5_0.25', u'N:E-5_0.25', u'N:C5_0.5', '!', u'N:B-4_0.25', u'N:A-4_0.25', u'N:G4_0.25', u'N:F4_0.25', '!', u'N:E-4_1.0', u'N:A-4_2.0', '!', u'N:F4_0.25', u'N:D4_0.25', u'C:[:D-4_0.5[:D-5_0.5', u'C:[:C4_0.5[:C5_0.5', '!', u'C:[:E-4_0.5[:E-5_0.5', u'N:G4_1.0', '!', u'N:C5_2.0', '!', u'N:A-4_0.25', u'N:F4_0.25', u'C:[:D-5_0.5[:D-6_0.5', u'C:[:C5_0.5[:C6_0.5', '!', u'C:[:E-5_0.5[:E-6_0.5', '!', u'N:G5_1.0', u'N:C6_3.0', '!', u'N:A-5_0.25', u'N:F5_0.25', u'N:E-5_0.25', u'N:G5_0.25', u'N:B-5_0.25', u'N:E-6_0.25', '!', u'N:B-5_0.25', u'N:G5_0.25', u'N:A-5_0.25', u'N:F5_0.25', u'N:D5_0.25', u'N:E-5_0.25', '!', u'N:G5_0.25', u'N:B-4_0.25', u'N:E-5_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:A-4_0.25', '!', u'N:F4_0.25', u'N:D4_0.25', u'N:E-4_0.5', 'R:0.5', '!', u'C:[:B-3_0.5[:E-4_0.5', u'C:[:B-3_0.5[:E-4_0.5', 'R:0.5', '!', 'R:0.5', '!'] +# b=['TS:3/8', 'CL:G', 'KS:-3', 'R:0.5', u'N:G5_0.5', u'N:F5_0.125', u'N:E-5_0.125', u'N:D5_0.125', u'N:C5_0.125', '!', u'N:B-4_1.0', u'N:A4_0.5', '!', 'R:1.5', '!', 'R:0.5', u'N:F5_0.25', u'N:D5_0.25', u'N:E-5_0.25', u'N:F5_0.25', u'N:D5_0.25', u'N:E-5_0.25', '!', u'N:F5_0.5', u'N:G5_0.5', u'N:E-5_0.5', '!', 'KS:-3', 'R:0.5', u'N:E-5_0.25', u'N:C5_0.25', u'N:D5_0.25', u'N:E-5_0.25', u'N:C5_0.25', u'N:D5_0.25', '!', u'N:E-5_0.5', u'N:F5_0.5', u'N:D5_0.5', '!', u'N:B-4_0.5', u'N:B-5_0.5', u'N:B-5_0.5', '!', u'N:G5_0.5', u'N:F5_0.25', u'N:E-5_0.25', u'N:D5_0.25', u'N:C5_0.25', '!', 'KS:-3', u'N:B-4_1.0', u'N:C5_0.25', u'N:A4_0.25', '!', u'N:B-4_0.5', 'R:0.5', 'R:0.5', '!', u'N:B-4_0.5', u'N:B-5_0.5', u'N:B-5_0.5', '!', u'N:G5_0.5', u'N:F5_0.25', u'N:E-5_0.25', u'N:D5_0.25', u'N:C5_0.25', '!', 'KS:-3', u'N:B-4_1.0', u'N:C5_0.25', u'N:A4_0.25', '!', u'C:[:A-4_0.5[:A-5_0.5', u'C:[:G4_0.5[:G5_0.5', u'C:[:B-4_0.5[:B-5_0.5', '!', u'N:D5_1.0', u'N:E-5_0.25', u'N:C5_0.25', '!', u'C:[:A-4_0.5[:A-5_0.5', u'C:[:G4_0.5[:G5_0.5', u'C:[:B-4_0.5[:B-5_0.5', '!', 'KS:-3', u'N:D5_1.0', 'R:0.5', '!', u'N:B-4_0.25', u'N:D5_0.25', u'N:F5_0.25', u'N:B-5_0.25', u'N:F5_0.25', u'N:D5_0.25', u'N:E-5_0.25', u'N:C5_0.25', u'N:A4_0.25', '!', u'N:B-4_0.25', u'N:D5_0.25', u'N:F4_0.25', u'N:B-4_0.25', u'N:F4_0.25', u'N:D4_0.25', u'N:E-4_0.25', u'N:C4_0.25', u'N:A3_0.25', '!', u'N:B-3_0.5', 'R:0.5', u'C:[:F3_0.5[:B-3_0.5', '!', u'C:[:F3_0.5[:B-3_0.5', 'R:0.5', 'R:0.5', '!', 'KS:-3', 'R:1.5', '!', 'R:0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', '!', u'N:B-5_1.0', u'N:D5_0.5', '!', u'N:E-5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', '!', u'N:B-5_1.0', u'N:E5_0.5', '!', 'KS:-3', u'N:F5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', u'N:C5_0.25', u'N:A4_0.25', u'N:B-4_0.25', '!', u'N:B-5_1.0', u'N:F5_0.5', '!', 'R:0.5', u'N:G-5_0.5', u'N:E-5_0.5', '!', 'R:0.5', u'N:E-5_0.5', u'N:A4_0.5', '!', 'R:0.5', u'N:B-4_0.5', u'N:D5_0.5', '!', u'N:F5_0.5', u'N:A5_0.5', u'N:B-5_0.5', '!', 'KS:-3', u'N:B-4_0.5', 'R:0.5', u'C:[:D4_0.5[:A-4_0.5', '!', u'C:[:D4_0.5[:A-4_0.5', 'R:0.5', 'R:0.5', '!', 'R:0.5', 'R:0.5', u'N:B-5_0.25', u'N:G5_0.5', u'N:C6_0.25', u'N:B-5_0.25', u'N:A-5_0.25', u'N:F5_0.5', u'N:B-5_0.25', u'N:A-5_0.25', '!', u'N:G5_0.25', u'N:E-5_0.5', u'N:A-5_0.25', u'N:G5_0.25', u'N:F5_0.25', u'N:D5_0.5', u'N:G5_0.25', u'N:F5_0.25', u'N:E-5_0.25', u'N:C5_0.5', u'N:F5_0.25', u'N:E-5_0.25', '!', u'N:D5_0.25', u'N:B-4_0.5', u'N:E-5_0.25', u'N:D5_0.25', u'N:C5_0.25', u'N:A-4_0.5', u'N:D5_0.25', u'N:C5_0.25', u'N:B-4_0.5', u'N:G4_0.5', '!', u'N:B-4_1.5', u'N:F4_0.5', 'KS:-3', u'N:E-4_0.5', u'N:D4_0.5', '!', u'N:E-5_0.25', u'N:G4_1.0', u'N:G5_0.25', u'N:F5_0.25', u'N:E-5_0.25', u'N:D5_0.25', u'N:E-5_0.25', u'N:C5_0.25', u'N:A-4_0.5', u'N:D5_0.25', u'N:C5_0.25', '!', u'N:B-4_1.0', u'N:G4_1.0', u'N:A-4_0.25', u'N:F4_0.5', u'N:G4_0.125', u'N:A-4_0.125', '!', u'N:G4_0.5', u'N:D5_0.5', u'N:E-5_0.5', '!', 'KS:-3', 'R:0.5', u'N:B-5_0.5', u'N:G5_0.5', '!', 'R:0.25', u'N:F5_0.25', u'N:G5_0.25', u'N:A-5_0.25', u'N:B-5_0.25', u'N:C6_0.25', '!', u'N:C6_0.25', u'N:B-5_0.25', u'N:A-5_0.25', u'N:G5_0.25', u'N:F5_0.25', u'N:D5_0.25', '!', u'N:E-5_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:E-4_0.25', u'N:D4_0.25', u'N:F4_0.25', u'N:A-4_0.25', '!', u'N:G4_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:E-5_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:A-4_0.25', u'N:F4_0.25', u'N:D4_0.25', '!', u'N:E-4_0.5', 'R:0.5', u'C:[:B-3_0.5[:E-4_0.5', '!', 'KS:-3', u'C:[:B-3_0.5[:E-4_0.5', 'R:0.5', 'R:0.5', '!', u'N:E-5_0.5', u'N:E-5_0.125', u'N:F5_0.125', u'N:E-5_0.125', u'N:D-5_0.125', u'N:C5_0.5', '!', 'R:0.5', u'N:A-5_0.5', u'N:A-5_0.5', '!', u'N:G5_0.5', u'N:G5_0.125', u'N:A-5_0.125', u'N:B-5_0.125', u'N:A-5_0.125', u'N:G5_0.5', '!', 'R:0.5', u'N:D-6_0.5', u'N:D-6_0.5', '!', 'KS:-3', u'N:C6_0.5', u'N:C6_0.125', u'N:D-6_0.125', u'N:E-6_0.125', u'N:D-6_0.125', u'N:C6_0.5', '!', 'R:0.5', u'N:F5_0.5', u'N:F5_0.5', '!', u'N:F5_0.25', u'N:E5_0.25', u'N:G5_0.25', u'N:E5_0.25', u'N:C5_0.25', u'N:B-4_0.25', '!', u'N:A-4_0.5', 'R:0.5', u'N:E-5_0.5', '!', u'N:E-5_0.25', u'N:D5_0.25', u'N:F5_0.25', u'N:D5_0.25', u'N:B-4_0.25', u'N:A-4_0.25', '!', 'KS:-3', u'N:G4_0.5', 'R:0.5', u'N:G5_0.5', '!', u'N:F5_0.5', 'R:0.5', u'N:A-5_0.5', '!', 'R:0.5', u'N:C6_0.5', u'N:B-5_0.125', u'N:A-5_0.125', u'N:G5_0.125', u'N:F5_0.125', '!', u'N:E-5_1.0', u'N:D5_0.5', '!', 'R:1.5', '!', 'R:0.5', u'N:B-5_0.25', u'N:G5_0.25', u'N:A-5_0.25', u'N:B-5_0.25', u'N:G5_0.25', u'N:A-5_0.25', '!', 'KS:-3', u'N:B-5_0.5', u'N:C6_0.5', u'N:A-5_0.5', '!', 'R:0.5', u'N:A-5_0.375', u'N:F5_0.25', u'N:G5_0.25', 'R:0.125', '!', u'N:A-5_0.5', u'N:B-5_0.5', u'N:G5_0.5', '!', u'N:E-5_0.5', u'N:E-6_0.5', u'N:E-6_0.5', '!', u'N:C6_0.5', u'N:B-5_0.25', u'N:A-5_0.25', u'N:G5_0.25', u'N:F5_0.25', '!', 'KS:-3', u'N:E-5_1.0', 'R:0.5', '!', u'N:E-5_0.5', 'R:0.5', 'R:0.5', '!', u'N:B-4_0.5', u'N:G5_0.25', u'N:D5_0.25', u'N:E-5_0.25', u'N:G5_0.25', u'N:D5_0.25', u'N:E-5_0.25', '!', u'N:C5_0.5', u'N:B-4_0.25', u'N:A-4_0.25', u'N:G4_0.25', u'N:F4_0.25', '!', 'KS:-3', u'N:E-4_1.0', u'N:F4_0.25', u'N:D4_0.25', '!', u'C:[:D-4_0.5[:D-5_0.5', u'C:[:C4_0.5[:C5_0.5', u'C:[:E-4_0.5[:E-5_0.5', '!', u'N:G4_1.0', u'N:A-4_0.25', u'N:F4_0.25', '!', u'C:[:D-5_0.5[:D-6_0.5', u'C:[:C5_0.5[:C6_0.5', u'C:[:E-5_0.5[:E-6_0.5', '!', 'KS:-3', u'N:G5_1.0', u'N:A-5_0.25', u'N:F5_0.25', '!', u'N:E-5_0.25', u'N:G5_0.25', u'N:B-5_0.25', u'N:E-6_0.25', u'N:B-5_0.25', u'N:G5_0.25', u'N:A-5_0.25', u'N:F5_0.25', u'N:D5_0.25', '!', u'N:E-5_0.25', u'N:G5_0.25', u'N:B-4_0.25', u'N:E-5_0.25', u'N:B-4_0.25', u'N:G4_0.25', u'N:A-4_0.25', u'N:F4_0.25', u'N:D4_0.25', '!', u'N:E-4_0.5', 'R:0.5', u'C:[:B-3_0.5[:E-4_0.5', '!', u'C:[:B-3_0.5[:E-4_0.5', 'R:0.5', 'R:0.5', '!'] + + +faa=FastAlignmentArrays() +alignment,finalValue,finalScore=faa.needleman_wunsch(a, b,isFast=False) +print finalScore +alignment,finalValue,finalScore=faa.needleman_wunsch(a, b,isFast=True) +print finalScore +score=NWunsch.NWunsch_getSimilarity(a,b) +print score +