def calcAccumulation(new_sol, newFrameLot, r, cost=True):
    stories = tracking.ordonnancement(new_sol)
    acc = np.zeros(shape=(len(EVENTS), 3), dtype=list)

    for plate in newFrameLot.lstFrames:
        for well in newFrameLot.lstFrames[plate]:
            for index in newFrameLot.lstFrames[plate][well]:
                print plate, well, index
                try:
                    costs = r[plate][well][index]
                except KeyError:
                    continue
                sourceC, targetC = accuracy.filtre(newFrameLot.lstFrames[plate][well][index])
                #                for b in range(len(sourceC)):
                #                    print "training set :", sourceC[b], targetC[b]
                if index not in stories[plate][well]:
                    continue
                solC = stories[plate][well][index]
                if type(solC.truth) == str:
                    print "attention, il n'y a pas de prediction pour cet index"
                    continue
                costs2 = filter(lambda x: x[1] == 1, zip(costs, solC.truth))

                predicted = formulation(filter(lambda x: x[1] == 1, zip(solC.hypotheses, solC.truth)), costs2)

                #                for k in range(len(predicted[0])):
                #                    print "predictions :", predicted[0][k], predicted[1][k]
                i = 0
                upletsVus = []
                for uplet in sourceC:
                    t, ttarg = accuracy.movement(uplet, s=None, tC=targetC[i])
                    for u in uplet:
                        # moi je voudrais aussi l'index dans predicted
                        ind, (p, ptarg) = movement(u, predicted)
                        if p == 1:
                            # c'est une apparition
                            try:
                                ind = predicted[1][-1].index(ttarg)
                            except ValueError:
                                continue
                            else:
                                upletsVus.append(ttarg)

                        #       pdb.set_trace()
                        if t == p:
                            test = (ttarg == ptarg) if t != 1 else (ttarg in ptarg)
                            if test and t != 1:
                                try:
                                    acc[t][0].append(predicted[2][ind])
                                except AttributeError:
                                    acc[t][0] = [predicted[2][ind]]
                            elif test and t == 1:
                                #                               pdb.set_trace()
                                try:
                                    acc[t][0].append(predicted[2][-1][ind])
                                except AttributeError:
                                    acc[t][0] = [predicted[2][-1][ind]]
                        else:
                            print "-------------------------------------------------------pas pareil..."
                            if p != -1:
                                try:
                                    acc[p][1].append(predicted[2][ind])
                                except AttributeError:
                                    acc[p][1] = [predicted[2][ind]]
                            else:
                                try:
                                    #                                    pdb.set_trace()
                                    acc[p][1].append(predicted[2][-1][ind])
                                except AttributeError:
                                    acc[p][1] = [predicted[2][-1][ind]]
                    i += 1
                # pdb.set_trace()
                for uplet in filter(lambda x: x != -1 and x not in sourceC, predicted[0]):
                    for u in uplet:
                        ind, (p, ptarg) = movement(u, predicted)
                        try:
                            acc[p][2].append(predicted[2][ind])
                        except AttributeError:
                            acc[p][2] = [predicted[2][ind]]
                # if upletsVus!=[]: pdb.set_trace()
                for u in filter(lambda x: x not in upletsVus, predicted[1][-1]):
                    p = 1
                    ind = predicted[1][-1].index(u)
                    try:
                        acc[p][2].append(predicted[2][ind])
                    except AttributeError:
                        acc[p][2] = [predicted[2][ind]]

    return acc
def calcAccuracy(new_sol, newFrameLot, tdict=None):
    stories = tracking.ordonnancement(new_sol) 
    acc = np.zeros(shape=(len(EVENTS), 2), dtype=np.int)
    acc2 = np.zeros(shape=(len(EVENTS), len(EVENTS)), dtype=np.int)
    compteur = [[0,0] for x in range(len(EVENTS))]
    
    visu = {}
    
    
    if tdict == None:
        for plate in newFrameLot.lstFrames:
            if plate not in visu:
                visu[plate]={}
            for well in newFrameLot.lstFrames[plate]:
                print plate, well, 'calculating accuracy on the whole video'
                if well not in visu[plate]:
                    visu[plate][well]={}
                for index in newFrameLot.lstFrames[plate][well]:
                    if index not in visu[plate][well]:
                        visu[plate][well][index]=[]
                    if index+1 not in visu[plate][well]:
                        visu[plate][well][index+1]=[]
                        
                    visuC=visu[plate][well][index] ; nextVisu=visu[plate][well][index+1]
                    #print index,
                    sourceC, targetC = filtre(newFrameLot.lstFrames[plate][well][index])
    #                for b in range(len(sourceC)):
    #                    print "training set :", sourceC[b], targetC[b]
                    if index not in stories[plate][well]:
                        continue
                    solC = stories[plate][well][index]
                    if type(solC.truth)==str:
                        print "attention, il n'y a pas de prediction pour cet index"
                        continue
                   
                    predicted =formulation(filter(lambda x: x[1]==1, zip(solC.hypotheses, solC.truth)))
    #                for k in range(len(predicted[0])):
    #                    print "predictions :", predicted[0][k], predicted[1][k]
                    i=0
                    for uplet in sourceC:
                        t, ttarg = movement(uplet, s = None, tC=targetC[i])
                        #print "truth", uplet, t, ttarg
                        
                        #compteur[0]=nb total de liens, compteur[1]=nb total de matchings 
                        compteur[t][0]+=max(len(uplet), len(ttarg)); compteur[t][1]+=1 
                        first = True
                        for u in uplet:
                            p, ptarg = movement(u, s=predicted, tC = None)
                        #   print "predit pour", u, " : ", p, ptarg
                            #pdb.set_trace()
                            if t==p: 
                                test = (ttarg==ptarg) if t!=1 else (ttarg in ptarg)
                                if test:
                                    #le matching est le bon et la cible egalement : j'enregistre acc[0]=nb de bons liens, acc[1]=nb de bons matchings
                                    acc[t][0]+=max(1, len(ttarg))
                                    if first: acc[t][1]+=1
                                    first = False
                                    #acc2[t][p]+=1
                                else:
#                                    donc la j'enregistre les erreurs, ici il y en a 
                                    if u!=-1:
                                        visuC.append(filter(lambda x: x.label==u, solC.singlets)[0].center)
                                    else:
                                        nextVisu.append(filter(lambda x: x.label==ttarg, solC.nextSinglets)[0].center)
                                    if t==1:
                                        for tt in ttarg:
                                            z, ztarg = movement (u, s=predicted, tC = tt, incomplet = True)
                                            acc2[t][z]+=1
                                    else:
                                        for tt in ttarg:
                                            if tt in ptarg:
                                                acc[t][0]+=1
                                            else:
                                                z, ztarg = movement(u, s=predicted, tC=tt, incomplet=True)
                                                acc2[t][z]+=1
                            else:
                                #print '-------------------------------------------------------pas pareil...'
                                if u!=-1:
                                    visuC.append(filter(lambda x: x.label==u, solC.singlets)[0].center)
                                else:
                                    nextVisu.append(filter(lambda x: x.label==ttarg, solC.nextSinglets)[0].center)
                                if len(ttarg)>1:
                                    if first:
                                        for tt in ttarg:
                                            z, ztarg = movement (u, s=predicted, tC = tt, incomplet = True)
                                            acc2[t][z]+=1
                                    first = False
                                else:
                                    acc2[t][p]+=1
                        i+=1
    else:
        for plate in newFrameLot.lstFrames:
            for well in tdict[plate]:
                for index in tdict[plate][well]:
                    print plate, well, index
                    sourceC, targetC = filtre(newFrameLot.lstFrames[plate][well][index])

    #                for b in range(len(sourceC)):
    #                    print "training set :", sourceC[b], targetC[b]
                    if index not in stories[plate][well]:
                        continue
                    solC = stories[plate][well][index]
                    if type(solC.truth)==str:
                        print "attention, il n'y a pas de prediction pour cet index"
                        continue
                   
                    predicted =formulation(filter(lambda x: x[1]==1, zip(solC.hypotheses, solC.truth)))
                    
    #                for k in range(len(predicted[0])):
    #                    print "predictions :", predicted[0][k], predicted[1][k]
                    i=0
                    for uplet in sourceC:
                        t, ttarg = movement(uplet, s = None, tC=targetC[i])
                        #print "truth", uplet, t, ttarg
                        
                        #compteur[0]=nb total de liens, compteur[1]=nb total de matchings 
                        compteur[t][0]+=max(len(uplet), len(ttarg)); compteur[t][1]+=1 
                        first = True
                        for u in uplet:
                            p, ptarg = movement(u, s=predicted, tC = None)
                         #   print "predit", p, ptarg
                            #pdb.set_trace()
                            if t==p:
                                test = (ttarg==ptarg) if t!=1 else (ttarg in ptarg)
                                if test:
                                    #le matching est le bon et la cible egalement : j'enregistre acc[0]=nb de bons liens, acc[1]=nb de bons matchings
                                    acc[t][0]+=max(1, len(ttarg))
                                    if first: acc[t][1]+=1
                                    first = False
                                    #acc2[t][p]+=1
                                else:
#                                    donc la j'enregistre les erreurs, ici il y en a 
                                    if t==1:
                                        for tt in ttarg:
                                            z, ztarg = movement (u, s=predicted, tC = tt, incomplet = True)
                                            acc2[t][z]+=1
                                    else:
                                        for tt in ttarg:
                                            if tt in ptarg:
                                                acc[t][0]+=1
                                            else:
                                                z, ztarg = movement(u, s=predicted, tC=tt, incomplet=True)
                                                acc2[t][z]+=1
                            else:
                                #print '-------------------------------------------------------pas pareil...'
                                if len(ttarg)>1:
                                    if first:
                                        for tt in ttarg:
                                            z, ztarg = movement (u, s=predicted, tC = tt, incomplet = True)
                                            acc2[t][z]+=1
                                    first = False
                                else:
                                    acc2[t][p]+=1
                                
                        i+=1
    return acc, acc2, np.array(compteur), visu
def trajBuilder(new_sol, training=False):
    
    stories = tracking.ordonnancement(new_sol); res = {}
    global movie_length
    
    for plate in stories:
        res.update({plate : {}})
        movie_length.update({plate : {}})
        for well in stories[plate]:
            print plate, well
            ensembleTraj = fHacktrack2.ensTraj()
            res[plate].update({well:ensembleTraj})
            movie_length[plate].update({well : max(stories[plate][well].keys())+1})
#            print ensembleTraj.numMitoses
#            print ensembleTraj.lstTraj
            num = 0; l=[0]; mergeList=-1; trajC=None
            for index in stories[plate][well]:
                print " INDEX ", index,
                solC = stories[plate][well][index]
                if type(solC.truth)==str:
                    l.append(index+1)
                    continue
                singlets = solC.singlets
                nextSinglets = solC.nextSinglets
                result =filter(lambda x: x[1]==1, zip(solC.hypotheses, solC.truth))
                
                for hyp in result:
                    #print hyp
                    #if index==86: pdb.set_trace()
                    s, t = hyp[0]; source = [] ; target = []; 
                    if type(s) in [np.int32, np.uint16] and s!=-1:
                        source.append(filter(lambda x: x.label == s, singlets)[0])
                    elif type(s)==tuple:        
                        for c in s:
                            source.append(filter(lambda x: x.label == c, singlets)[0])
                    if type(t) in [np.int32, np.uint16] and t!=-1:
                        target.append(filter(lambda x: x.label == t, nextSinglets)[0])
                    elif type(t)==tuple:        
                        for c in t:
                            target.append(filter(lambda x: x.label == c, nextSinglets)[0])  
                    
                    incoming = len(source) ; outcoming= len(target)
                    mit = (outcoming>1) 
#                    if mit: pdb.set_trace()
                    num+=1
                    if incoming == 0:
#                        print "APPEAR"
                        for c in target:
                            newTraj= fHacktrack2.trajectoire(num, c.center[0], c.center[1], index+1, c.label)
                            newTraj.longueurs=[index+1]
                            newTraj.fractions=[1]
                            ensembleTraj.add(newTraj)
                            num+=1
                        continue
                    elif outcoming ==0:
#                        print "DISAPPEAR"
                        if index in l:
                            #pdb.set_trace()#en fait ce sont au moins les trajectoires qui commencent en 0 et finissent en 0 ie les apparitions disparitions en 0
                            for c in source:
                                newTraj = fHacktrack2.trajectoire(num, c.center[0], c.center[1], index, c.label)
                                newTraj.longueurs = [index]
                                newTraj.fractions=[1]
                                ensembleTraj.add(newTraj)
                                num+=1
                        continue
                    elif incoming == 1: 
#                        print "FROM ONE"
                        c = source[0]
                        incomingTraj = ensembleTraj.findLabelFrame(c.label, index)
                        if outcoming <= len(incomingTraj):
                            first = True; ll=[]; lf=[]
#                            for traj in incomingTraj:
#                                ll.extend(traj.longueurs)
#                                lf.extend(traj.fractions)
#                            if ll==[] and index>0:
#                                pdb.set_trace()
                            for traj in incomingTraj:
                                try:
                                    t = target.pop()
                                except IndexError:
                                    continue
                                else:
                                    traj.ajoutPoint(t.center[0], t.center[1], index+1, t.label)
#                                    traj.longueurs = ll; traj.fractions = lf
                                    if first: numC = traj.numCellule
                                    if mit: 
#                                        print "ajout mitose"
                                        traj.split(index); traj.numCellule = numC; first = False
                                        #traj.ajoutMomentInteressant(c.center[0], c.center[1], index)
                                        ensembleTraj.numMitoses+=1
                        else:
                            i = 0; first = True; ll=[]; lf=[]
#                            for traj in incomingTraj:
#                                ll.extend(traj.longueurs)
#                                lf.extend(traj.fractions)
#                            if ll==[] and index>0:
#                                pdb.set_trace()    
                            for t in target:
                                try:
                                    incomingTraj[i].ajoutPoint(t.center[0], t.center[1], index+1, t.label)
#                                    incomingTraj[i].longueurs = ll; incomingTraj[i].fractions = lf
                                    if first: 
                                        numC = incomingTraj[i].numCellule
                                        trajC = incomingTraj[i]  
                                        mergeList = incomingTraj[i].fusion                   
                                    if mit: 
#                                        print "ajout mitose"
                                        incomingTraj[i].split(index); incomingTraj[i].numCellule = numC; first = False
                                        #incomingTraj[i].ajoutMomentInteressant(c.center[0], c.center[1], index)
                                        ensembleTraj.numMitoses+=1
                                    i+=1
                                except IndexError:
                                    if not mit: 
                                        #ici on y arrive a t=0 quand aucune trajectoire n'est initialise ou cas de split a quatre sorti du TS
                                        if index>0 and training==False: pdb.set_trace()
                                        num+=1
                                        newTraj = fHacktrack2.trajectoire(num, c.center[0], c.center[1], index, c.label)
                                        newTraj.ajoutPoint(t.center[0], t.center[1], index+1, t.label)
                                        newTraj.longueurs=[index]; newTraj.fractions = [1]
                                    if first: 
                                        numC = num    
                                        if index>0 and training==False:
                                            print hyp
                                            pdb.set_trace()
                                    if mit:
                                        #ici, quand j'ai une mitose je copie toute la trajectoire precedente dans la nouvelle OU PAS ?
                                        newTraj = fHacktrack2.trajectoire(numC, c.center[0], c.center[1], index, c.label)
                                        newTraj.ajoutPoint(t.center[0], t.center[1], index+1, t.label)
                                        newTraj.longueurs = incomingTraj[0].longueurs if incomingTraj !=[] else [index]
                                        newTraj.fractions = incomingTraj[0].fractions if incomingTraj !=[] else [1]
                                        #print id(trajC), numC, hyp, mergeList
                                        #pdb.set_trace()
                                        newTraj.fusion=list(mergeList) if type(mergeList)==list else mergeList
                                        #pdb.set_trace()
#                                        print "ajout mitose"
                             
                                        newTraj.split(index)
                                        first = False
                                        #newTraj.ajoutMomentInteressant(c.center[0], c.center[1], index)
                                        ensembleTraj.numMitoses+=1
                                    #pdb.set_trace()
                                    ensembleTraj.add(newTraj)
            
                    elif incoming >1:
                        if outcoming>1:
                            raise
#                        print "FROM MORE THAN ONE"
                        t = target[0]; tt=None
                        if index>0:
                            tt=[]; ll=[]; lf=[]
                            for c in source:
                                incomingTraj = ensembleTraj.findLabelFrame(c.label, index)
                                try:
                                    tt.append(incomingTraj[0])
                                except IndexError:
                                    pass
                                else:
                                    k=0
                                    for lon in incomingTraj[0].longueurs:
                                        ll.append(lon)
                                        lf.append(incomingTraj[0].fractions[k]/float(incoming))
                                        k+=1
#                        if ll==[] and index>0:
#                            pdb.set_trace()        
                        i=0
                        for c in source:
                            try:
                                trajC = tt[i]
                                trajC.longueurs = ll; trajC.fractions = lf
#                                pdb.set_trace()
                            except:
                                #on tombe ici a t=0 mais est-ce qu'on y tombe apres ? oui si on calcule les trajectoires du training
                                #set pcq il y a des evenements elimines par defaut (mvt a quatre)
                                if index>0 and training==False: pdb.set_trace()
                                num+=1
                                trajC = fHacktrack2.trajectoire(num, c.center[0], c.center[1], index, c.label)
                                trajC.longueurs=[index for bb in range(incoming)]; trajC.fractions = [1/float(incoming) for bb in range(incoming)]
                                ensembleTraj.add(trajC)
                            finally:    
                                trajC.ajoutPoint(t.center[0], t.center[1], index+1, t.label)
                                #print id(trajC), trajC.numCellule, trajC.fusion
                                #pdb.set_trace()
                                trajC.merge(index)
                            i+=1
                            #incomingTraj[0].ajoutMomentInteressant(c.center[0], c.center[1], index)
    return res