changeset 2:46fb79167a61 tip

Main Code
author Victor Padilla <victor.padilla.mc@gmail.com>
date Mon, 04 May 2015 22:56:18 +0200
parents 0f7f611deca4
children
files Automatism/BatchOMR.py Automatism/BatchOMR.pyc Automatism/__init__.py Automatism/__init__.pyc MainMultiOMR.py MainMultiOMR.pyc Preprocessing/__init__.pyc Preprocessing/movements.py Preprocessing/movements.pyc Preprocessing/ossia.py Preprocessing/ossia.pyc Preprocessing/preomr.py Preprocessing/preomr.pyc Process/Clustering.py Process/Clustering.pyc Process/FullScoreAlignment.py Process/FullScoreAlignment.pyc Process/PipelineAlignment.py Process/PipelineAlignment.pyc Process/SymbolConversion.py Process/SymbolConversion.pyc Process/Voting.py Process/Voting.pyc Process/__init__.py Process/__init__.pyc Result/ExcellData.py Result/ExcellData.pyc Result/ProcessGroundS2.py Result/ProcessGroundS2.pyc Result/__init__.py Result/__init__.pyc __init__.py __init__.pyc mainGDI.py mainGDI.pyc setup.py setup.pyc sikuli/CP.sikuli/1415700984115.png sikuli/CP.sikuli/1415710175004.png sikuli/CP.sikuli/1415710207538.png sikuli/CP.sikuli/1415710242258.png sikuli/CP.sikuli/1415710292754.png sikuli/CP.sikuli/1415710897800.png sikuli/CP.sikuli/1415711065949.png sikuli/CP.sikuli/1415711761225.png sikuli/CP.sikuli/1415711940063.png sikuli/CP.sikuli/1415791421283.png sikuli/CP.sikuli/1415791723329.png sikuli/CP.sikuli/1415791774505.png sikuli/CP.sikuli/1415791801451.png sikuli/CP.sikuli/CP.html sikuli/CP.sikuli/CP.py sikuli/CP.sikuli/cerrar.png sikuli/PS.sikuli/1415626157985.png sikuli/PS.sikuli/1415626436439.png sikuli/PS.sikuli/1415628223695.png sikuli/PS.sikuli/1415628257531.png sikuli/PS.sikuli/1415700984115.png sikuli/PS.sikuli/1415785439675.png sikuli/PS.sikuli/1415785928359.png sikuli/PS.sikuli/1415786066894.png sikuli/PS.sikuli/1415791940762.png sikuli/PS.sikuli/1415791956757.png sikuli/PS.sikuli/1415791980822.png sikuli/PS.sikuli/1415792044614.png sikuli/PS.sikuli/1415792076797.png sikuli/PS.sikuli/1415792095379.png sikuli/PS.sikuli/1415876625654.png sikuli/PS.sikuli/1415876704875.png sikuli/PS.sikuli/1415876822838.png sikuli/PS.sikuli/1415876912038.png sikuli/PS.sikuli/1415882981586.png sikuli/PS.sikuli/1415963511508.png sikuli/PS.sikuli/1416238736460.png sikuli/PS.sikuli/1416238784250.png sikuli/PS.sikuli/1416239106139.png sikuli/PS.sikuli/1416239184735.png sikuli/PS.sikuli/1417434097757.png sikuli/PS.sikuli/2014-11-13_12-53-25.png sikuli/PS.sikuli/PS.html sikuli/PS.sikuli/PS.py sikuli/PS.sikuli/cerrar.png sikuli/SE.sikuli/1415700984115.png sikuli/SE.sikuli/1415716688669.png sikuli/SE.sikuli/1415716721174.png sikuli/SE.sikuli/1415716758693.png sikuli/SE.sikuli/1415716942199.png sikuli/SE.sikuli/1415716964607.png sikuli/SE.sikuli/1415717208007.png sikuli/SE.sikuli/1415717515734.png sikuli/SE.sikuli/1415717913108.png sikuli/SE.sikuli/1415718431424.png sikuli/SE.sikuli/1415718524045.png sikuli/SE.sikuli/1415718695577.png sikuli/SE.sikuli/1415792167505.png sikuli/SE.sikuli/1415792179506.png sikuli/SE.sikuli/1415792207078.png sikuli/SE.sikuli/1415792424959.png sikuli/SE.sikuli/1415792444947.png sikuli/SE.sikuli/1415792490785.png sikuli/SE.sikuli/1415792510149.png sikuli/SE.sikuli/1415792536736.png sikuli/SE.sikuli/1415792587415.png sikuli/SE.sikuli/1415792640839.png sikuli/SE.sikuli/1415792786165.png sikuli/SE.sikuli/1415792803049.png sikuli/SE.sikuli/1415963853362.png sikuli/SE.sikuli/1417614329432.png sikuli/SE.sikuli/1417614361971.png sikuli/SE.sikuli/2014-11-12_11-58-32.png sikuli/SE.sikuli/2014-11-13_13-34-35.png sikuli/SE.sikuli/DropDown.png sikuli/SE.sikuli/SE.html sikuli/SE.sikuli/SE.py sikuli/SE.sikuli/cerrar.png sikuli/SS.sikuli/1415700984115.png sikuli/SS.sikuli/1415701611441.png sikuli/SS.sikuli/1415701865784.png sikuli/SS.sikuli/1415701911562.png sikuli/SS.sikuli/1415701967254.png sikuli/SS.sikuli/1415702019016.png sikuli/SS.sikuli/1415702225757.png sikuli/SS.sikuli/1415706040951.png sikuli/SS.sikuli/1415792857317.png sikuli/SS.sikuli/1415792869010.png sikuli/SS.sikuli/1415792905305.png sikuli/SS.sikuli/1415792946298.png sikuli/SS.sikuli/1415792965001.png sikuli/SS.sikuli/1415793010197.png sikuli/SS.sikuli/1415798023757.png sikuli/SS.sikuli/1415798271832.png sikuli/SS.sikuli/1415885604725.png sikuli/SS.sikuli/1415963913666.png sikuli/SS.sikuli/1416922791607.png sikuli/SS.sikuli/2014-11-13_13-34-35.png sikuli/SS.sikuli/SS.html sikuli/SS.sikuli/SS.py sikuli/SS.sikuli/cerrar.png sikuli/SS.sikuli/select.png test.py
diffstat 140 files changed, 4966 insertions(+), 0 deletions(-) [+]
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')
+    
Binary file Automatism/BatchOMR.pyc has changed
--- /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
Binary file Automatism/__init__.pyc has changed
--- /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
Binary file MainMultiOMR.pyc has changed
Binary file Preprocessing/__init__.pyc has changed
--- /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
Binary file Preprocessing/movements.pyc has changed
--- /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
Binary file Preprocessing/ossia.pyc has changed
--- /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
Binary file Preprocessing/preomr.pyc has changed
--- /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) 
+         
+         
Binary file Process/Clustering.pyc has changed
--- /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
Binary file Process/FullScoreAlignment.pyc has changed
--- /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
Binary file Process/PipelineAlignment.pyc has changed
--- /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
Binary file Process/SymbolConversion.pyc has changed
--- /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
Binary file Process/Voting.pyc has changed
--- /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
Binary file Process/__init__.pyc has changed
--- /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
Binary file Result/ExcellData.pyc has changed
--- /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
+               
+
Binary file Result/ProcessGroundS2.pyc has changed
--- /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
Binary file Result/__init__.pyc has changed
--- /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
Binary file __init__.pyc has changed
--- /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
Binary file mainGDI.pyc has changed
--- /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'],
+
+  )
Binary file setup.pyc has changed
Binary file sikuli/CP.sikuli/1415700984115.png has changed
Binary file sikuli/CP.sikuli/1415710175004.png has changed
Binary file sikuli/CP.sikuli/1415710207538.png has changed
Binary file sikuli/CP.sikuli/1415710242258.png has changed
Binary file sikuli/CP.sikuli/1415710292754.png has changed
Binary file sikuli/CP.sikuli/1415710897800.png has changed
Binary file sikuli/CP.sikuli/1415711065949.png has changed
Binary file sikuli/CP.sikuli/1415711761225.png has changed
Binary file sikuli/CP.sikuli/1415711940063.png has changed
Binary file sikuli/CP.sikuli/1415791421283.png has changed
Binary file sikuli/CP.sikuli/1415791723329.png has changed
Binary file sikuli/CP.sikuli/1415791774505.png has changed
Binary file sikuli/CP.sikuli/1415791801451.png has changed
--- /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
Binary file sikuli/CP.sikuli/cerrar.png has changed
Binary file sikuli/PS.sikuli/1415626157985.png has changed
Binary file sikuli/PS.sikuli/1415626436439.png has changed
Binary file sikuli/PS.sikuli/1415628223695.png has changed
Binary file sikuli/PS.sikuli/1415628257531.png has changed
Binary file sikuli/PS.sikuli/1415700984115.png has changed
Binary file sikuli/PS.sikuli/1415785439675.png has changed
Binary file sikuli/PS.sikuli/1415785928359.png has changed
Binary file sikuli/PS.sikuli/1415786066894.png has changed
Binary file sikuli/PS.sikuli/1415791940762.png has changed
Binary file sikuli/PS.sikuli/1415791956757.png has changed
Binary file sikuli/PS.sikuli/1415791980822.png has changed
Binary file sikuli/PS.sikuli/1415792044614.png has changed
Binary file sikuli/PS.sikuli/1415792076797.png has changed
Binary file sikuli/PS.sikuli/1415792095379.png has changed
Binary file sikuli/PS.sikuli/1415876625654.png has changed
Binary file sikuli/PS.sikuli/1415876704875.png has changed
Binary file sikuli/PS.sikuli/1415876822838.png has changed
Binary file sikuli/PS.sikuli/1415876912038.png has changed
Binary file sikuli/PS.sikuli/1415882981586.png has changed
Binary file sikuli/PS.sikuli/1415963511508.png has changed
Binary file sikuli/PS.sikuli/1416238736460.png has changed
Binary file sikuli/PS.sikuli/1416238784250.png has changed
Binary file sikuli/PS.sikuli/1416239106139.png has changed
Binary file sikuli/PS.sikuli/1416239184735.png has changed
Binary file sikuli/PS.sikuli/1417434097757.png has changed
Binary file sikuli/PS.sikuli/2014-11-13_12-53-25.png has changed
--- /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")
+
+
Binary file sikuli/PS.sikuli/cerrar.png has changed
Binary file sikuli/SE.sikuli/1415700984115.png has changed
Binary file sikuli/SE.sikuli/1415716688669.png has changed
Binary file sikuli/SE.sikuli/1415716721174.png has changed
Binary file sikuli/SE.sikuli/1415716758693.png has changed
Binary file sikuli/SE.sikuli/1415716942199.png has changed
Binary file sikuli/SE.sikuli/1415716964607.png has changed
Binary file sikuli/SE.sikuli/1415717208007.png has changed
Binary file sikuli/SE.sikuli/1415717515734.png has changed
Binary file sikuli/SE.sikuli/1415717913108.png has changed
Binary file sikuli/SE.sikuli/1415718431424.png has changed
Binary file sikuli/SE.sikuli/1415718524045.png has changed
Binary file sikuli/SE.sikuli/1415718695577.png has changed
Binary file sikuli/SE.sikuli/1415792167505.png has changed
Binary file sikuli/SE.sikuli/1415792179506.png has changed
Binary file sikuli/SE.sikuli/1415792207078.png has changed
Binary file sikuli/SE.sikuli/1415792424959.png has changed
Binary file sikuli/SE.sikuli/1415792444947.png has changed
Binary file sikuli/SE.sikuli/1415792490785.png has changed
Binary file sikuli/SE.sikuli/1415792510149.png has changed
Binary file sikuli/SE.sikuli/1415792536736.png has changed
Binary file sikuli/SE.sikuli/1415792587415.png has changed
Binary file sikuli/SE.sikuli/1415792640839.png has changed
Binary file sikuli/SE.sikuli/1415792786165.png has changed
Binary file sikuli/SE.sikuli/1415792803049.png has changed
Binary file sikuli/SE.sikuli/1415963853362.png has changed
Binary file sikuli/SE.sikuli/1417614329432.png has changed
Binary file sikuli/SE.sikuli/1417614361971.png has changed
Binary file sikuli/SE.sikuli/2014-11-12_11-58-32.png has changed
Binary file sikuli/SE.sikuli/2014-11-13_13-34-35.png has changed
Binary file sikuli/SE.sikuli/DropDown.png has changed
--- /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")
+
+
+
+
+
+
+
Binary file sikuli/SE.sikuli/cerrar.png has changed
Binary file sikuli/SS.sikuli/1415700984115.png has changed
Binary file sikuli/SS.sikuli/1415701611441.png has changed
Binary file sikuli/SS.sikuli/1415701865784.png has changed
Binary file sikuli/SS.sikuli/1415701911562.png has changed
Binary file sikuli/SS.sikuli/1415701967254.png has changed
Binary file sikuli/SS.sikuli/1415702019016.png has changed
Binary file sikuli/SS.sikuli/1415702225757.png has changed
Binary file sikuli/SS.sikuli/1415706040951.png has changed
Binary file sikuli/SS.sikuli/1415792857317.png has changed
Binary file sikuli/SS.sikuli/1415792869010.png has changed
Binary file sikuli/SS.sikuli/1415792905305.png has changed
Binary file sikuli/SS.sikuli/1415792946298.png has changed
Binary file sikuli/SS.sikuli/1415792965001.png has changed
Binary file sikuli/SS.sikuli/1415793010197.png has changed
Binary file sikuli/SS.sikuli/1415798023757.png has changed
Binary file sikuli/SS.sikuli/1415798271832.png has changed
Binary file sikuli/SS.sikuli/1415885604725.png has changed
Binary file sikuli/SS.sikuli/1415963913666.png has changed
Binary file sikuli/SS.sikuli/1416922791607.png has changed
Binary file sikuli/SS.sikuli/2014-11-13_13-34-35.png has changed
--- /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")
+
+
+
+
+
+
Binary file sikuli/SS.sikuli/cerrar.png has changed
Binary file sikuli/SS.sikuli/select.png has changed
--- /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
+