def createClustersAndMatchingMatrices(parts, atoms, numOfClusters, disFactor):
    vecs = []
    mats = []
    for atom in atoms:
        closeVectors = []
        tmp = []
        fig = plt.figure()
        i=1
        for part in parts:
            retVal = getAtomFromFrac(part, atom, simpleDis)
            if retVal is None:
                continue
            frac,  dis, vecAtom, bias, bestScale, temporalScale, offset, _= retVal
            tmp.append((dis, frac))
            amplitude = np.max(vecAtom) - np.min(vecAtom)
            if(dis > amplitude*disFactor):
                continue
            closeVectors.append(frac)
            if(i>25):
                continue
            curr = fig.add_subplot(5,5,i)
            i+=1
            
            plt.title('bias: ' + str(bias) + ' scale: ' + str(bestScale) + 
                ' bestTemporalScale: ' + str(temporalScale) + ' dis: ' + str(dis))
            curr.plot(part, c='b')
            rng = xrange(offset, offset + len(frac))
            curr.plot(rng, vecAtom, c='g')
            curr.plot(rng, frac, c='r')
            #plt.show()
        print len(tmp), len(closeVectors)
        if(len(closeVectors) < numOfClusters):
            tmp = sorted(tmp, key=lambda tup: tup[0])
            clusteredVectors = [t[1] for t in tmp[:numOfClusters]]
        else:
            lengthCounter = {}
            for vec in closeVectors:
                lengthCounter[len(vec)] = lengthCounter.get(len(vec), []) + [vec]
            residum = len(closeVectors)%numOfClusters
            clusteredVectors = []
            tmpNumOfClusters = numOfClusters
            last = len(lengthCounter) - 1
            for i, (vecLen, sameLengthVecs) in enumerate(lengthCounter.items()):
                #if(vecLen <= len(sameLengthVecs)):
                    #sameLengthVecs, idx = kmeans2(np.array(sameLengthVecs), max(1, int(float(numOfClusters)*vecLen/len(closeVectors))))
                numOfClusterPerLength = int(round(float(numOfClusters)*len(sameLengthVecs)/len(closeVectors)))
                numOfClusterPerLength = min(numOfClusterPerLength, tmpNumOfClusters) if i!=last else tmpNumOfClusters
                tmpNumOfClusters -= numOfClusterPerLength
                if(numOfClusterPerLength == 0):
                    continue
                sameLengthVecs, idx = kmeans(np.array(sameLengthVecs), numOfClusterPerLength)
                for v in sameLengthVecs:
                    clusteredVectors.append(pe.toList(v))
                #clusteredVectors = clusteredVectors + sameLengthVecs

        vecs.append(pe.toList(clusteredVectors))
        if(len(vecs) > 1):
            last = vecs[-2]
            mat = []
            for atom1 in last:
                row = []
                for atom2 in clusteredVectors:
                    row.append(getDistanceBetweenAtoms(atom1, atom2))
                mat.append(row)
            mats.append(mat)
        if(len(vecs)==len(atoms)):
            next = vecs[0]
            mat = []
            for atom1 in clusteredVectors:
                row = []
                for atom2 in next:
                    row.append(getDistanceBetweenAtoms(atom1, atom2))
                mat.append(row)
            mats.append(mat)  
    return vecs, mats
def appendAtom(atom1, atom2):
    atom1 = pe.toList(atom1)
    atom2 = pe.toList(atom2)
    last = (atom1[-1] + atom2[1])/2.0
    beforeLast = (atom1[-2] + atom2[0])/2.0
    return atom1[:-2] + [beforeLast, last] + atom2[2:]