def reBuildEvent( connection, file, tmin=None, tmax=None, pool = None ): pool = AnimalPool( ) pool.loadAnimals( connection ) #pool.loadDetection( start = tmin, end = tmax ) rear = {} for animal in range( 1 , 5 ): rear[animal] = EventTimeLineCached( connection, file, "Rear isolated", animal, minFrame=tmin, maxFrame=tmax ) centerWindow = {} for animal in range( 1 , 5 ): centerWindow[animal] = EventTimeLineCached(connection, file, "Center Zone", animal, minFrame=tmin, maxFrame=tmax ) periphery = {} for animal in range( 1 , 5 ): periphery[animal] = EventTimeLineCached(connection, file, "Periphery Zone", animal, minFrame=tmin, maxFrame=tmax ) for animal in range( 1 , 5 ): eventName1 = "Rear in centerWindow" print ( eventName1 ) eventName2 = "Rear at periphery" print ( eventName2 ) rearCenterTimeLine = EventTimeLine( None, eventName1 , animal , None , None , None , loadEvent=False ) rearPeripheryTimeLine = EventTimeLine( None, eventName2 , animal , None , None , None , loadEvent=False ) resultCenter={} resultPeriphery={} dicRear = rear[ animal ].getDictionnary() dicCenter = centerWindow[ animal ].getDictionnary() dicPeriphery = periphery[ animal ].getDictionnary() for t in dicRear.keys(): if ( t in dicCenter ): resultCenter[t] = True if (t in dicPeriphery ): resultPeriphery[t] = True rearCenterTimeLine.reBuildWithDictionnary( resultCenter ) rearPeripheryTimeLine.reBuildWithDictionnary( resultPeriphery ) rearCenterTimeLine.endRebuildEventTimeLine(connection) rearPeripheryTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger( connection ) t.addLog( "Build Event Rear in centerWindow" , tmin=tmin, tmax=tmax ) t.addLog( "Build Event Rear at periphery" , tmin=tmin, tmax=tmax ) print( "Rebuild event finished." )
def getNumberOfEventWithList( connection, file, eventName, idAnimalA , animalList, minFrame=None, maxFrame=None ): sumOfEvent = 0 for animalCandidate in animalList: timeLine = EventTimeLineCached( connection , file, eventName , idAnimalA , animalCandidate.baseId, minFrame=minFrame, maxFrame=maxFrame ) sumOfEvent += timeLine.getNbEvent() return sumOfEvent
def getDurationOfEventWithList( connection, file, eventName, idAnimalA , animalList, minFrame=None, maxFrame=None ): durationOfEvent = 0 for animalCandidate in animalList: timeLine = EventTimeLineCached( connection , file, eventName , idAnimalA , animalCandidate.baseId, minFrame=minFrame, maxFrame=maxFrame ) durationOfEvent += timeLine.getTotalLength() return durationOfEvent
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax, lightLoad=True) ''' load the contact timeline for each pair of animals ''' anogenitalSniffTimeLine = {} passiveAnogenitalSniffTimeLine = {} for animal in range(1, pool.getNbAnimals() + 1): for idAnimalB in range(1, pool.getNbAnimals() + 1): if (animal == idAnimalB): continue anogenitalSniffTimeLine[animal, idAnimalB] = EventTimeLineCached( connection, file, "Oral-genital Contact", animal, idAnimalB, minFrame=tmin, maxFrame=tmax) # create an empty timeline for other contacts passiveAnogenitalSniffTimeLine[idAnimalB, animal] = EventTimeLine( None, 'Passive oral-genital Contact', idAnimalB, animal, loadEvent=False) anogenitalSniffDico = {} for animal in range(1, pool.getNbAnimals() + 1): for idAnimalB in range(1, pool.getNbAnimals() + 1): if (animal == idAnimalB): continue anogenitalSniffDico[animal, idAnimalB] = anogenitalSniffTimeLine[ animal, idAnimalB].getDictionary(minFrame=tmin, maxFrame=tmax) passiveAnogenitalSniffTimeLine[idAnimalB, animal].reBuildWithDictionnary( anogenitalSniffDico[animal, idAnimalB]) passiveAnogenitalSniffTimeLine[ idAnimalB, animal].endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Passive oral-genital Contact", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): eventUndetected = 'Undetected exclusive' if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) ''' load the existing detection timeline for animal ''' detectionTimeLine = {} dicoDetection = {} undetectedTimeLine = {} for animal in range(1, pool.getNbAnimals() + 1): detectionTimeLine[animal] = EventTimeLineCached(connection, file, 'Detection', animal, minFrame=tmin, maxFrame=tmax) dicoDetection[animal] = detectionTimeLine[animal].getDictionary( minFrame=tmin, maxFrame=tmax) undetectedTimeLine[animal] = EventTimeLine(None, eventUndetected, animal, loadEvent=False) '''select the frames where the animals are not detected''' undetectedDico = {} for animal in range(1, pool.getNbAnimals() + 1): undetectedDico[animal] = {} for t in range(tmin, tmax + 1): if t not in dicoDetection[animal]: undetectedDico[animal][t] = True ##################################################### #reduild all events based on dictionary for animal in range(1, pool.getNbAnimals() + 1): undetectedTimeLine[animal].reBuildWithDictionnary( undetectedDico[animal]) undetectedTimeLine[animal].endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Exclusive undetected events", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): pool = AnimalPool() pool.loadAnimals(connection) #pool.loadDetection( start = tmin, end = tmax ) ''' load contact matrix ''' contact = {} group3In = {} group3Out = {} for idAnimalA in range(1, 5): contact[idAnimalA] = EventTimeLineCached(connection, file, "Contact", idAnimalA, minFrame=tmin, maxFrame=tmax) group3In[idAnimalA] = EventTimeLine(connection, "Group 3 make", idAnimalA, loadEvent=False) group3Out[idAnimalA] = EventTimeLine(connection, "Group 3 break", idAnimalA, loadEvent=False) ''' process group ''' for idAnimalA in range(1, 5): for idAnimalB in range(1, 5): for idAnimalC in range(1, 5): ''' check impossible combination (avoid 2 animals with same id) ''' test = {} test[idAnimalA] = True test[idAnimalB] = True test[idAnimalC] = True if not len(test.keys()) == 3: continue ''' process group ''' group3 = EventTimeLineCached(connection, file, "Group3", idAnimalA, idAnimalB, idAnimalC, minFrame=tmin, maxFrame=tmax) eventList = group3.getEventList() for event in eventList: t = event.startFrame - 1 if (not contact[idAnimalA].hasEvent(t)): group3In[idAnimalA].addPunctualEvent(t) if (not contact[idAnimalB].hasEvent(t)): group3In[idAnimalB].addPunctualEvent(t) if (not contact[idAnimalC].hasEvent(t)): group3In[idAnimalC].addPunctualEvent(t) t = event.endFrame + 1 if (not contact[idAnimalA].hasEvent(t)): group3Out[idAnimalA].addPunctualEvent(t) if (not contact[idAnimalB].hasEvent(t)): group3Out[idAnimalB].addPunctualEvent(t) if (not contact[idAnimalC].hasEvent(t)): group3Out[idAnimalC].addPunctualEvent(t) ''' save all ''' for idAnimal in range(1, 5): group3In[idAnimal].endRebuildEventTimeLine(connection) group3Out[idAnimal].endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Group3 Make Break", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' use the pool provided or create it''' if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax) ''' Event OralSide Sequence ''' nbAnimal = pool.getNbAnimals() contact = {} oralOral = {} oralGenital = {} oralOralDico = {} oralGenitalDico = {} EVENT_MIN_LEN = 10 for idAnimalB in pool.animalDictionnary.keys(): print(pool.animalDictionnary[idAnimalB]) meanSizeB = pool.animalDictionnary[idAnimalB].getMeanBodyLength( tmax=tmax) for animal in pool.animalDictionnary.keys(): if (idAnimalB == animal): continue ''' contact[animal, idAnimalB] = EventTimeLine( connection, "Contact", animal, idAnimalB, minFrame=tmin, maxFrame=tmax ) ''' oralOral[animal, idAnimalB] = EventTimeLineCached(connection, file, "Oral-oral Contact", animal, idAnimalB, minFrame=tmin, maxFrame=tmax) oralGenital[animal, idAnimalB] = EventTimeLineCached( connection, file, "Oral-genital Contact", animal, idAnimalB, minFrame=tmin, maxFrame=tmax) oralOralDico[animal, idAnimalB] = oralOral[animal, idAnimalB].getDictionnary() oralGenitalDico[animal, idAnimalB] = oralGenital[ animal, idAnimalB].getDictionnary() window = 60 ''' oral oral followed by a oral-genital ''' eventName = "seq oral oral - oral genital" print(eventName) for animal in range(1, nbAnimal + 1): for idAnimalB in range(1, nbAnimal + 1): if (animal == idAnimalB): continue selOO_OG_TimeLine = EventTimeLine(None, eventName, animal, idAnimalB, None, None, loadEvent=False) print(selOO_OG_TimeLine.eventNameWithId) oralOralTimeLine = oralOral[animal, idAnimalB] oralGeniDico = oralGenitalDico[animal, idAnimalB] oralGeniTimeLine = oralGenital[animal, idAnimalB] for event in oralOralTimeLine.eventList: endFrame = event.endFrame if (event.duration() >= EVENT_MIN_LEN): continue for t in range(endFrame, endFrame + window + 1): if (t in oralGeniDico): event2 = oralGeniTimeLine.getEventAt(t) if (event2.duration() >= EVENT_MIN_LEN): start = event.startFrame end = event2.endFrame selOO_OG_TimeLine.addEvent(Event(start, end)) break selOO_OG_TimeLine.endRebuildEventTimeLine(connection) window = 60 ''' oral A genital B followed by oral oral ''' eventName = "seq oral geni - oral oral" print(eventName) for animal in range(1, nbAnimal + 1): for idAnimalB in range(1, nbAnimal + 1): if (animal == idAnimalB): continue selOG_OO_TimeLine = EventTimeLine(None, eventName, animal, idAnimalB, None, None, loadEvent=False) print(selOG_OO_TimeLine.eventNameWithId) oralGenitalTimeLine = oralGenital[animal, idAnimalB] ooDico = oralOralDico[animal, idAnimalB] oralOralTimeLine = oralOral[animal, idAnimalB] for event in oralGenitalTimeLine.eventList: endFrame = event.endFrame if (event.duration() >= EVENT_MIN_LEN): continue for t in range(endFrame, endFrame + window + 1): if (t in ooDico): event2 = oralOralTimeLine.getEventAt(t) if (event2.duration() >= EVENT_MIN_LEN): start = event.startFrame end = event2.endFrame selOG_OO_TimeLine.addEvent(Event(start, end)) break selOG_OO_TimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Oral Side Sequence", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' use pool cache if available ''' if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax) ''' three animals are following each others with nose-to-anogenital contacts animals are moving this is a combination of Train2 events (train2 events must be calculated before this event) ''' #deleteEventTimeLineInBase(connection, "Train3" ) ''' build a list of train 2 for each time point ''' time = {} train3 = {} for idAnimalA in range(1, 5): for idAnimalB in range(1, 5): if (idAnimalA == idAnimalB): continue train2TimeLine = EventTimeLineCached(connection, file, "Train2", idAnimalA, idAnimalB, minFrame=tmin, maxFrame=tmax) for t in train2TimeLine.getDictionnary(): train = Train2(idAnimalA, idAnimalB) if (not t in time): time[t] = [] #print ( t , ":" , train.idA , " -> ", train.idB , "*" ) time[t].append(train) for t in time: trainList = time[t] for trainSource in trainList: for trainTarget in trainList: if (trainSource == trainTarget): continue isValid = "" ''' test chain link between train2 events ''' if trainSource.idB == trainTarget.idA: id1 = trainSource.idA id2 = trainSource.idB id3 = trainTarget.idB if not (id1, id2, id3) in train3: train3[id1, id2, id3] = {} train3[id1, id2, id3][t] = True isValid = ": validated train 3" #print ( t , ":" , trainSource.idA , " -> ", trainSource.idB, "--->", trainTarget.idA , " -> ", trainTarget.idB , isValid ) ''' save data ''' for idAnimalA in range(1, 5): for idAnimalB in range(1, 5): for idAnimalC in range(1, 5): if (idAnimalA, idAnimalB, idAnimalC) in train3: trainTimeLine = EventTimeLine(None, "Train3", idAnimalA, idAnimalB, idAnimalC, loadEvent=False) trainTimeLine.reBuildWithDictionnary(train3[idAnimalA, idAnimalB, idAnimalC]) #trainTimeLine.removeEventsBelowLength( 5 ) trainTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Train3", tmin=tmin, tmax=tmax) print("Rebuild event finished.") return
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' Animal A is stopped (built-in event): Move social: animal A is stopped and in contact with another animal. Move isolated: animal A is stopped and not in contact with any other animal. ''' pool = AnimalPool() pool.loadAnimals(connection) isInContactSourceDictionnary = {} moveSourceTimeLine = {} for animal in pool.animalDictionnary.keys(): ''' Load source stop timeLine and revert it to get the move timeline If the animal is not detected, this will result in a move. To avoid this we mask with the detection. ''' moveSourceTimeLine[animal] = EventTimeLine(connection, "Stop", animal, minFrame=tmin, maxFrame=tmax, inverseEvent=True) detectionTimeLine = EventTimeLine(connection, "Detection", animal, minFrame=tmin, maxFrame=tmax) moveSourceTimeLine[animal].keepOnlyEventCommonWithTimeLine( detectionTimeLine) ''' load contact dictionnary with another animal ''' for animalB in pool.animalDictionnary.keys(): if animal == animalB: print('Same identity') continue else: isInContactSourceDictionnary[( animal, animalB)] = EventTimeLineCached( connection, file, "Contact", animal, animalB, minFrame=tmin, maxFrame=tmax).getDictionnary() for animal in pool.animalDictionnary.keys(): #initialisation of a dic for isolated move moveIsolatedResult = {} for animalB in pool.animalDictionnary.keys(): # initialisation of a dic for move in contact for each individual of the cage moveSocialResult = {} if animal == animalB: print('Same identity') continue else: ''' loop over eventlist''' for moveEvent in moveSourceTimeLine[animal].eventList: ''' for each event we seek in t and search a match in isInContactDictionnary between animal and animalB ''' for t in range(moveEvent.startFrame, moveEvent.endFrame + 1): if t in isInContactSourceDictionnary[(animal, animalB)]: moveSocialResult[t] = True else: moveIsolatedResult[t] = True ''' save move social at the end of the search for each animal''' moveSocialResultTimeLine = EventTimeLine(None, "Move in contact", idA=animal, idB=animalB, idC=None, idD=None, loadEvent=False) moveSocialResultTimeLine.reBuildWithDictionnary( moveSocialResult) moveSocialResultTimeLine.endRebuildEventTimeLine(connection) ''' save move isolated at the end of the complete process for animalA''' moveIsolatedResultTimeLine = EventTimeLine(None, "Move isolated", idA=animal, idB=None, idC=None, idD=None, loadEvent=False) moveIsolatedResultTimeLine.reBuildWithDictionnary(moveIsolatedResult) moveIsolatedResultTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Move", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent( connection, file, tmin=None, tmax=None , pool = None ): ''' Nest 3 ''' print("[NEST 3] : Assume that there is no occlusion, does not work with anonymous animals") if ( pool == None ): pool = AnimalPool( ) pool.loadAnimals( connection ) pool.loadDetection( start = tmin, end = tmax , lightLoad=True ) if ( len ( pool.getAnimalList() ) != 4 ): print( "[NEST3 Cancelled] 4 animals are required to build nest3.") return contact = {} for idAnimalA in range( 1 , 5 ): for idAnimalB in range( 1 , 5 ): if idAnimalA != idAnimalB: contact[idAnimalA,idAnimalB] = EventTimeLineCached( connection, file, "Contact", idAnimalA, idAnimalB, minFrame=tmin, maxFrame=tmax ).getDictionnary() stopDictionnary = {} for idAnimalA in range( 1 , 5 ): stopDictionnary[idAnimalA] = EventTimeLineCached( connection, file, "Stop", idAnimalA, minFrame=tmin, maxFrame=tmax ).getDictionnary() nest3TimeLine = {} for idAnimalA in range( 1 , 5 ): # the id will be the one excluded from nest. nest3TimeLine[idAnimalA] = EventTimeLine( None, "Nest3" , idAnimalA, loadEvent=False ) animalList = pool.getAnimalList() result = {} for idAnimalA in range( 1 , 5 ): result[idAnimalA] = {} for t in range( tmin, tmax+1 ): isNest = False nbAnimalAtT = 0 animalDetectedList = [] for animal in animalList: if t in animal.detectionDictionnary: nbAnimalAtT+=1 animalDetectedList.append( animal ) #print( str(t) + " : " + str( nbAnimalAtT ) ) #print("TEST") graph = nx.Graph(); # add nodes for animal in animalDetectedList: graph.add_node( animal ) for animalA in animalDetectedList: for animalB in animalDetectedList: if animalA != animalB: # add an edge if t in contact[animalA.baseId,animalB.baseId]: graph.add_edge( animalA, animalB ) # list of CC from the biggest to the smallest listCC = sorted(nx.connected_components( graph ), key=len, reverse=True) if ( len( listCC ) == 2 ): # we have 2 groups # check if animals in the biggest group are stopped. allStoppedInBiggestGroup = True for animal in list( listCC[0] ): if not ( t in stopDictionnary[animal.baseId] ): allStoppedInBiggestGroup = False break if allStoppedInBiggestGroup: if ( len( listCC[1] ) == 1 ): # the 2nd group (and the smallest) has only one mouse animal = list(listCC[1])[0] result[ animal.baseId ][ t ] = True ''' largestCC = len ( max(nx.connected_components( graph ), key=len) ) #print( str( t ) + " : " + str ( len( largestCC ) ) ) print( str( t ) + " : " + str ( largestCC ) + " / " + str( nbAnimalAtT ) ) if largestCC == nbAnimalAtT : isNest= True if isNest == True: print( "ADD PUNCTUAL") result[t] = True; ''' for idAnimalA in range( 1 , 5 ): # the id will be the one excluded from nest. nest3TimeLine[idAnimalA].reBuildWithDictionnary( result[idAnimalA] ) # remove very small events nest3TimeLine[idAnimalA].removeEventsBelowLength( 2 ) nest3TimeLine[idAnimalA].mergeCloseEvents( 3 ) nest3TimeLine[idAnimalA].endRebuildEventTimeLine(connection) #nest4TimeLine.reBuildWithDictionnary( result ) #nest4TimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger( connection ) t.addLog( "Build Event Nest3" , tmin=tmin, tmax=tmax ) print( "Rebuild event finished." )
def reBuildEvent( connection, file, tmin=None, tmax=None, pool = None ): ''' use the pool provided or create it''' if ( pool == None ): pool = AnimalPool( ) pool.loadAnimals( connection ) pool.loadDetection( start = tmin, end = tmax ) ''' Event Rear5: - the animal is rearing - distinction between rearing in contact with one or several animals and rearing isolated from the others ''' contact = {} for idAnimalA in pool.animalDictionnary.keys(): print(pool.animalDictionnary[idAnimalA]) contact[idAnimalA] = EventTimeLineCached( connection, file, "Contact", idAnimalA, minFrame=tmin, maxFrame=tmax ) contactDico = contact[idAnimalA].getDictionnary() eventName1 = "Rear isolated" eventName2 = "Rear in contact" print ( "A rears") rearSocialTimeLine = EventTimeLine( None, eventName2 , idAnimalA , None , None , None , loadEvent=False ) rearIsolatedTimeLine = EventTimeLine( None, eventName1 , idAnimalA , None , None , None , loadEvent=False ) resultSocial={} resultIsolated={} animalA = pool.animalDictionnary[idAnimalA] #print ( animalA ) dicA = animalA.detectionDictionnary for t in dicA.keys(): slope = dicA[t].getBodySlope() if ( slope == None): continue if ( abs( slope ) < BODY_SLOPE_THRESHOLD ): continue; if (t in contactDico.keys()): #print("social") resultSocial[t] = True else: #print("isolated") resultIsolated[t] = True rearSocialTimeLine.reBuildWithDictionnary( resultSocial ) rearIsolatedTimeLine.reBuildWithDictionnary( resultIsolated ) rearSocialTimeLine.endRebuildEventTimeLine( connection ) rearIsolatedTimeLine.endRebuildEventTimeLine( connection ) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger( connection ) t.addLog( "Build Event Rear5" , tmin=tmin, tmax=tmax ) print( "Rebuild event finished." )
def reBuildEvent( connection, file, tmin=None, tmax=None, pool = None ): pool = AnimalPool( ) pool.loadAnimals( connection ) #pool.loadDetection( start = tmin, end = tmax ) contact = {} for idAnimalA in range( 1 , 5 ): for idAnimalB in range( 1 , 5 ): if ( idAnimalA == idAnimalB ): continue contact[idAnimalA, idAnimalB] = EventTimeLineCached( connection, file, "Contact", idAnimalA, idAnimalB, minFrame=tmin, maxFrame=tmax ) #fait une matrice de tous les contacts à deux possibles for idAnimalA in range( 1 , 5 ): for idAnimalB in range( 1 , 5 ): if( idAnimalA == idAnimalB ): continue for idAnimalC in range( 1 , 5 ): if( idAnimalA == idAnimalC ): continue if( idAnimalB == idAnimalC ): continue for idAnimalD in range( 1 , 5 ): if( idAnimalA == idAnimalD ): continue if( idAnimalB == idAnimalD ): continue if( idAnimalC == idAnimalD ): continue eventName = "Group2" print ( eventName ) groupTimeLine = EventTimeLine( None, eventName , idAnimalA , idAnimalB , None , None , loadEvent=False ) result={} dicAB = contact[ idAnimalA , idAnimalB ].getDictionnary() dicAC = contact[ idAnimalA , idAnimalC ].getDictionnary() dicAD = contact[ idAnimalA , idAnimalD ].getDictionnary() dicBC = contact[ idAnimalB , idAnimalC ].getDictionnary() dicBD = contact[ idAnimalB , idAnimalD ].getDictionnary() for t in dicAB.keys(): if ( t in dicAC or t in dicAD or t in dicBC or t in dicBD ): continue else: result[t]=True groupTimeLine.reBuildWithDictionnary( result ) groupTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger( connection ) t.addLog( "Build Event Group 2" , tmin=tmin, tmax=tmax ) print( "Rebuild event finished." )
''' pool.loadDetection( start = min_dur, end = max_dur) for animal in pool.animalDictionnary.keys(): print ( pool.animalDictionnary[animal].RFID ) #total distance traveled totalDistance = pool.animalDictionnary[animal].getDistance(tmin = min_dur, tmax = max_dur) resTotalDistance = [file, pool.animalDictionnary[animal].RFID, min_dur, max_dur, totalDistance] text_file.write( "{}\t{}\t{}\t{}\t{}\n".format( file, pool.animalDictionnary[animal].RFID, min_dur, max_dur, totalDistance ) ) ''' nightEventTimeLine = EventTimeLineCached(connection, file, "night", minFrame=tmin, maxFrame=tmax) n = 1 for eventNight in nightEventTimeLine.getEventList(): startNight = eventNight.startFrame endNight = eventNight.endFrame print("Night: ", n) for animal in pool.animalDictionnary.keys(): for behavEvent in behaviouralEventOneMouse: print("computing individual event: {}".format(behavEvent))
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax, lightLoad=True) contactDicoDico = {} approachDico = {} for animal in range(1, pool.getNbAnimals() + 1): for idAnimalB in range(1, pool.getNbAnimals() + 1): if (animal == idAnimalB): continue ''' I take the dictionnary of event of the contact event, that's why I put DicoDico ''' contactDicoDico[animal, idAnimalB] = EventTimeLineCached( connection, file, "Contact", animal, idAnimalB, minFrame=tmin, maxFrame=tmax).getDictionnary() ''' This one is the dico of event ''' approachDico[animal, idAnimalB] = EventTimeLineCached( connection, file, "Social approach", animal, idAnimalB, minFrame=tmin, maxFrame=tmax ) #fait une matrice de toutes les approches à deux possibles for animal in range(1, pool.getNbAnimals() + 1): for idAnimalB in range(1, pool.getNbAnimals() + 1): if (animal == idAnimalB): continue eventName = "Approach contact2" print(eventName) appContactTimeLine = EventTimeLine(None, eventName, animal, idAnimalB, None, None, loadEvent=False) for eventApp in approachDico[animal, idAnimalB].eventList: ''' new code: ''' for t in range( eventApp.endFrame, eventApp.endFrame + TIME_WINDOW_BEFORE_EVENT + 1): if (t in contactDicoDico[animal, idAnimalB]): appContactTimeLine.eventList.append(eventApp) break ''' old code(slow) bug: est ce que ca n aurait pas du etre eventContact.startFrame ? ou eventApp.endFrame-TIME_WINDOW_BEFORE_EVENT, eventApp.endFrame+TIME_WINDOW_BEFORE_EVENT ? for eventContact in contactDicoDico[animal, idAnimalB].eventList: if (eventApp.overlapInT(eventContact.endFrame-TIME_WINDOW_BEFORE_EVENT, eventContact.endFrame+TIME_WINDOW_BEFORE_EVENT) == True): appContactTimeLine.eventList.append(eventApp) ''' appContactTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Approach Contact2", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' use pool cache if available ''' if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax) ''' two animals are following each others with nose-to-anogenital contacts animals are moving ''' #deleteEventTimeLineInBase(connection, "Train2" ) contactHeadGenital = {} for animal in range(1, pool.getNbAnimals() + 1): for idAnimalB in range(1, pool.getNbAnimals() + 1): if (animal == idAnimalB): continue contactHeadGenital[animal, idAnimalB] = EventTimeLineCached( connection, file, "Oral-genital Contact", animal, idAnimalB, minFrame=tmin, maxFrame=tmax) for animal in range(1, pool.getNbAnimals() + 1): for idAnimalB in range(1, pool.getNbAnimals() + 1): if (animal == idAnimalB): continue eventName = "Train2" print(eventName) trainTimeLine = EventTimeLine(None, eventName, animal, idAnimalB, loadEvent=False) result = {} dicAB = contactHeadGenital[animal, idAnimalB].getDictionnary() for t in dicAB.keys(): speedA = pool.animalDictionnary[animal].getSpeed(t) speedB = pool.animalDictionnary[idAnimalB].getSpeed(t) if (speedA != None and speedB != None): if (speedA > SPEED_THRESHOLD_HIGH and speedB > SPEED_THRESHOLD_HIGH): result[t] = True trainTimeLine.reBuildWithDictionnary(result) trainTimeLine.removeEventsBelowLength(5) trainTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Train2", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' Animal A is stopped (built-in event): Stop social: animal A is stopped and in contact with any other animal. Stop isolated: animal A is stopped and not in contact with any other animal. ''' pool = AnimalPool() pool.loadAnimals(connection) #pool.loadDetection( start = tmin, end = tmax ) isInContactSourceDictionnary = {} stopSourceTimeLine = {} for animal in range(1, 5): ''' Load source stop timeLine ''' stopSourceTimeLine[animal] = EventTimeLineCached(connection, file, "Stop", animal, minFrame=tmin, maxFrame=tmax) ''' load contact dictionnary with whatever animal ''' isInContactSourceDictionnary[animal] = EventTimeLineCached( connection, file, "Contact", animal, minFrame=tmin, maxFrame=tmax).getDictionnary() eventName2 = "Stop in contact" eventName1 = "Stop isolated" for animal in range(1, 5): print(eventName1, eventName2) stopSocialResult = {} stopIsolatedResult = {} ''' loop over eventlist''' for stopEvent in stopSourceTimeLine[animal].eventList: ''' for each event we seek in t and search a match in isInContactDictionnary ''' for t in range(stopEvent.startFrame, stopEvent.endFrame + 1): if t in isInContactSourceDictionnary[animal]: stopSocialResult[t] = True else: stopIsolatedResult[t] = True ''' save stop social ''' stopSocialResultTimeLine = EventTimeLine(None, eventName2, animal, None, None, None, loadEvent=False) stopSocialResultTimeLine.reBuildWithDictionnary(stopSocialResult) stopSocialResultTimeLine.endRebuildEventTimeLine(connection) ''' save stop isolated ''' stopIsolatedResultTimeLine = EventTimeLine(None, eventName1, animal, None, None, None, loadEvent=False) stopIsolatedResultTimeLine.reBuildWithDictionnary(stopIsolatedResult) stopIsolatedResultTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Stop", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def computeProfile(file, minT, maxT, night): connection = sqlite3.connect( file ) pool = AnimalPool( ) pool.loadAnimals( connection ) animalData = {} for animal in pool.animalDictionnary.keys(): print( "computing individual animal: {}".format( animal )) rfid = pool.animalDictionnary[animal].RFID print( "RFID: {}".format( rfid ) ) animalData[rfid]= {} animalData[rfid]["animal"] = pool.animalDictionnary[animal] animalData[rfid]["file"] = file genoA = None try: genoA=pool.animalDictionnary[animal].genotype except: pass for behavEvent in behaviouralEventOneMouse[:-2]: print( "computing individual event: {}".format(behavEvent)) behavEventTimeLine = EventTimeLineCached( connection, file, behavEvent, animal, minFrame=minT, maxFrame=maxT ) totalEventDuration = behavEventTimeLine.getTotalLength() nbEvent = behavEventTimeLine.getNumberOfEvent(minFrame = minT, maxFrame = maxT ) print( "total event duration: " , totalEventDuration ) animalData[rfid][behavEventTimeLine.eventName+" TotalLen"] = totalEventDuration animalData[rfid][behavEventTimeLine.eventName+" Nb"] = nbEvent print(behavEventTimeLine.eventName, genoA, behavEventTimeLine.idA, totalEventDuration, nbEvent) header = ["file","strain","sex","group","day","exp","RFID","genotype", "user1", "minTime","maxTime"] for name in header: text_file.write( "{}\t".format ( name ) ) for kAnimal in animalData: animalData[kAnimal]["experiment"] = file COMPUTE_TOTAL_DISTANCE = True if ( COMPUTE_TOTAL_DISTANCE == True ): animalData[kAnimal]["animal"].loadDetection( start=minT, end=maxT, lightLoad = True ) animalData[kAnimal]["totalDistance"] = animalData[kAnimal]["animal"].getDistance( tmin=minT,tmax=maxT)/100 else: animalData[kAnimal]["totalDistance"] = "totalDistance" #write event keys firstAnimalKey = next(iter(animalData)) firstAnimal = animalData[firstAnimalKey] for k in firstAnimal.keys(): text_file.write( "{}\t".format( k.replace(" ", "") ) ) text_file.write("\n") for kAnimal in animalData: text_file.write( "{}\t".format( file ) ) text_file.write( "{}\t".format( "strain" ) ) text_file.write( "{}\t".format( "sex" ) ) text_file.write( "{}\t".format( night ) ) text_file.write( "{}\t".format( "exp" ) ) text_file.write( "{}\t".format( animalData[kAnimal]["animal"].RFID ) ) text_file.write( "{}\t".format( animalData[kAnimal]["animal"].genotype ) ) text_file.write( "{}\t".format( minT ) ) text_file.write( "{}\t".format( maxT ) ) for kEvent in firstAnimal.keys(): text_file.write( "{}\t".format( animalData[kAnimal][kEvent] ) ) text_file.write( "\n" ) return animalData
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' use the pool provided or create it''' if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax, lightLoad=True) ''' Event Water Zone - the animal is in the zone around the water source - the animal is stopped in this zone for ''' for animal in pool.animalDictionnary.keys(): print(pool.animalDictionnary[animal]) eventName1 = "Water Zone" eventName2 = "Water Stop" print("A is in the zone around the water source") print(eventName1) waterZoneTimeLine = EventTimeLine(None, eventName1, animal, None, None, None, loadEvent=False) waterStopTimeLine = EventTimeLine(None, eventName2, animal, None, None, None, loadEvent=False) stopTimeLine = EventTimeLineCached(connection, file, "Stop", animal, minFrame=None, maxFrame=None) stopTimeLineDictionary = stopTimeLine.getDictionary() resultWaterZone = {} resultWaterStop = {} animalA = pool.animalDictionnary[animal] #print ( animalA ) dicA = animalA.detectionDictionnary for t in dicA.keys(): if (dicA[t].getDistanceToPoint(xPoint=398, yPoint=353) == None): continue #Check if the animal is entering the zone around the water point: if (dicA[t].getDistanceToPoint(xPoint=398, yPoint=353) <= MAX_DISTANCE_TO_POINT * 2): resultWaterZone[t] = True #Check if the animal is drinking (the animal should be in a tight zone around the water point and be stopped): if (dicA[t].getDistanceToPoint(xPoint=398, yPoint=353) <= MAX_DISTANCE_TO_POINT): if t in stopTimeLineDictionary.keys(): resultWaterStop[t] = True waterZoneTimeLine.reBuildWithDictionnary(resultWaterZone) waterZoneTimeLine.endRebuildEventTimeLine(connection) waterStopTimeLine.reBuildWithDictionnary(resultWaterStop) waterStopTimeLine.removeEventsBelowLength( maxLen=MIN_WATER_STOP_DURATION) waterStopTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Water Point", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' Nest 3 ''' print( "[NEST 3] : Assume that there is no occlusion, does not work with anonymous animals" ) if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax, lightLoad=True) if (len(pool.getAnimalList()) != 4): print("[NEST3 Cancelled] 4 animals are required to build nest3.") return contact = {} for idAnimalA in range(1, 5): for idAnimalB in range(1, 5): if idAnimalA != idAnimalB: contact[idAnimalA, idAnimalB] = EventTimeLineCached( connection, file, "Contact", idAnimalA, idAnimalB, minFrame=tmin, maxFrame=tmax).getDictionnary() stopDictionnary = {} for idAnimalA in range(1, 5): stopDictionnary[idAnimalA] = EventTimeLineCached( connection, file, "Stop", minFrame=tmin, maxFrame=tmax).getDictionnary() nest3TimeLine = {} for idAnimalA in range(1, 5): # the id will be the one excluded from nest. nest3TimeLine[idAnimalA] = EventTimeLine(None, "Nest3_", idA=idAnimalA, loadEvent=False) pool.loadAnonymousDetection() animalList = pool.getAnimalList() result = {} for idAnimalA in range(1, 5): result[idAnimalA] = {} #Added by Alice on 21/07/2020, to check tmax = pool.getMaxDetectionT() for t in range(tmin, tmax + 1): isNest = False nbAnimalAtT = 0 animalDetectedList = [] anonymousDetectionList = pool.getAnonymousDetection(t) for animal in animalList: if t in animal.detectionDictionnary: nbAnimalAtT += 1 animalDetectedList.append(animal) #print( str(t) + " : " + str( nbAnimalAtT ) ) #print("TEST") graph = nx.Graph() # add nodes for animal in animalDetectedList: graph.add_node(animal) for animalA in animalDetectedList: for animalB in animalDetectedList: if animalA != animalB: # add an edge if t in contact[animalA.baseId, animalB.baseId]: graph.add_edge(animalA, animalB) # check with anonymous detection. Check contact if anonymousDetectionList != None: # manage anonymous # print( t , "manage anonymous") ''' # load all masks for animal in animalDetectedList: animal.loadMask( t ) ''' for detectionA in anonymousDetectionList: # anonymous with anonymous for detectionB in anonymousDetectionList: # anonymous with anonymous if detectionA != detectionB: distance = detectionA.getDistanceTo(detectionB) if distance != None: if distance < DISTANCE_CONTACT_MASS_CENTER: graph.add_edge(detectionA, detectionB) # print("Adding edge with mask (det anonymous to det anonymous)") for detection in anonymousDetectionList: for animal in animalDetectedList: distance = detection.getDistanceTo( animal.getDetectionAt(t)) if distance != None: if distance < DISTANCE_CONTACT_MASS_CENTER: #if detection.getMask().isInContactWithMask( animal.getDetectionAt ( t ).getMask() ): graph.add_edge(animal, detection) # print("Adding edge with mask") # list of CC from the biggest to the smallest listCC = sorted(nx.connected_components(graph), key=len, reverse=True) if (len(listCC) == 2): # we have 2 groups # check if animals in the biggest group are stopped. allStoppedInBiggestGroup = True for animal in list(listCC[0]): if isinstance(animal, Animal): if not (t in stopDictionnary[animal.baseId]): allStoppedInBiggestGroup = False break if allStoppedInBiggestGroup: if (len(listCC[1]) == 1 ): # the 2nd group (and the smallest) has only one mouse animal = list(listCC[1])[0] if isinstance(animal, Animal): result[animal.baseId][t] = True for idAnimalA in range(1, 5): # the id will be the one excluded from nest. nest3TimeLine[idAnimalA].reBuildWithDictionnary(result[idAnimalA]) # remove very small events nest3TimeLine[idAnimalA].removeEventsBelowLength(2) # merge flashing events nest3TimeLine[idAnimalA].mergeCloseEvents(3) nest3TimeLine[idAnimalA].endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Nest3", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
print(file) connection = sqlite3.connect(file) pool = AnimalPool() pool.loadAnimals(connection) MODE_MULTI_GENOTYPE = False if (len(pool.getGenotypeList()) > 1): MODE_MULTI_GENOTYPE = True print("Mode multi genotype: ", MODE_MULTI_GENOTYPE) animal = {} nightEventTimeLine = EventTimeLineCached(connection, file, "night", minFrame=tmin, maxFrame=tmax) n = 1 header = [ "file", "event", "RFID_A", "geno_A", "RFID_B", "geno_B", "minTime", "maxTime", "dur", "nb" ] for name in header: text_file.write("{}\t".format(name)) text_file.write("{}\n".format("night")) for eventNight in nightEventTimeLine.getEventList(): minT = eventNight.startFrame
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' Animal A is stopped (built-in event): revert the event to have move events Move social: animal A is moving and in contact with another animal. Move isolated: animal A is moving and not in contact with any other animal. ''' pool = AnimalPool() pool.loadAnimals(connection) if len(pool.animalDictionnary.keys()) == 1: print('Only one animal in database.') '''if the animal has been tested alone, only the move isolated event will be computed.''' moveSourceTimeLine = {} animal = 1 ''' Load source stop timeLine and revert it to get the move timeline If the animal is not detected, this will result in a move. To avoid this we mask with the detection. ''' moveSourceTimeLine[animal] = EventTimeLine(connection, "Stop", animal, minFrame=tmin, maxFrame=tmax, inverseEvent=True) detectionTimeLine = EventTimeLine(connection, "Detection", animal, minFrame=tmin, maxFrame=tmax) moveSourceTimeLine[animal].keepOnlyEventCommonWithTimeLine( detectionTimeLine) # initialisation of a dic for isolated move moveIsolatedResult = {} ''' loop over eventlist''' for moveEvent in moveSourceTimeLine[animal].eventList: for t in range(moveEvent.startFrame, moveEvent.endFrame + 1): moveIsolatedResult[t] = True ''' save move isolated at the end of the complete process for animalA''' moveIsolatedResultTimeLine = EventTimeLine(None, "Move isolated", idA=animal, idB=None, idC=None, idD=None, loadEvent=False) moveIsolatedResultTimeLine.reBuildWithDictionnary(moveIsolatedResult) moveIsolatedResultTimeLine.endRebuildEventTimeLine(connection) else: print('More than one animal in database.') isInContactSourceDictionnary = {} moveSourceTimeLine = {} moveIsolatedTimeLine = {} for animal in pool.animalDictionnary.keys(): ''' Load source stop timeLine and revert it to get the move timeline If the animal is not detected, this will result in a move. To avoid this we mask with the detection. ''' moveSourceTimeLine[animal] = EventTimeLine(connection, "Stop", animal, minFrame=tmin, maxFrame=tmax, inverseEvent=True) detectionTimeLine = EventTimeLine(connection, "Detection", animal, minFrame=tmin, maxFrame=tmax) moveSourceTimeLine[animal].keepOnlyEventCommonWithTimeLine( detectionTimeLine) #by default let's say that all move are isolated; next we will extract frames which are in contact from this time line. moveIsolatedTimeLine[animal] = moveSourceTimeLine[animal] ''' load contact dictionary with another animal ''' for animalB in pool.animalDictionnary.keys(): if animal == animalB: print('Same identity') continue else: isInContactSourceDictionnary[( animal, animalB)] = EventTimeLineCached( connection, file, "Contact", animal, animalB, minFrame=tmin, maxFrame=tmax).getDictionnary() moveIsolatedDic = {} for animal in pool.animalDictionnary.keys(): #initialisation of a dic for isolated move moveIsolatedDic[animal] = moveIsolatedTimeLine[ animal].getDictionary() for animalB in pool.animalDictionnary.keys(): # initialisation of a dic for move in contact for each individual of the cage framesToRemoveFromMoveIsolatedTimeLine = [] moveSocialResult = {} if animal == animalB: print('Same identity') continue else: ''' loop over eventlist''' for moveEvent in moveIsolatedTimeLine[animal].eventList: ''' for each event we seek in t and search a match in isInContactDictionnary between animal and animalB ''' for t in range(moveEvent.startFrame, moveEvent.endFrame + 1): if t in isInContactSourceDictionnary[(animal, animalB)]: moveSocialResult[t] = True framesToRemoveFromMoveIsolatedTimeLine.append( t) ''' save move social at the end of the search for each animal''' # clean the dictionary of the move and stop events from frames that are overlapping with exclusive contacts for t in framesToRemoveFromMoveIsolatedTimeLine: moveIsolatedDic[animal].pop(t, None) moveSocialResultTimeLine = EventTimeLine(None, "Move in contact", idA=animal, idB=animalB, idC=None, idD=None, loadEvent=False) moveSocialResultTimeLine.reBuildWithDictionnary( moveSocialResult) moveSocialResultTimeLine.endRebuildEventTimeLine( connection) ''' save move isolated at the end of the complete process for animalA''' moveIsolatedResultTimeLine = EventTimeLine(None, "Move isolated", idA=animal, idB=None, idC=None, idD=None, loadEvent=False) moveIsolatedResultTimeLine.reBuildWithDictionnary( moveIsolatedDic[animal]) moveIsolatedResultTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Move", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' use the pool provided or create it''' if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax) ''' Event FollowZone: - the two animals are moving at a speed >5 cm/s (SPEED_THRESHOLD_LOW) - the angles between the two animals are less than 45° apart - the mass center of the follower is within a follow zone of one mean body length of width and two mean body lengths of length - either the animal B is in contact with another one (FollowZone Social) or the animal B is not in contact with any other animal (except A at the end of the follow event; FollowZone Isolated) - update 17 may 2018: now works with n animals ''' contact = {} for idAnimalB in pool.animalDictionnary.keys(): print(pool.animalDictionnary[idAnimalB]) meanSizeB = pool.animalDictionnary[idAnimalB].getMeanBodyLength( tmax=tmax) for animal in pool.animalDictionnary.keys(): if (idAnimalB == animal): continue contact[animal, idAnimalB] = EventTimeLineCached(connection, file, "Contact", animal, idAnimalB, minFrame=tmin, maxFrame=tmax) #contact[idAnimalB] = EventTimeLine( connection, "Contact", idAnimalB ) for idAnimalB in pool.animalDictionnary.keys(): for animal in pool.animalDictionnary.keys(): if (animal == idAnimalB): continue allAnimals = list(pool.animalDictionnary.keys()) allAnimals.remove(animal) allAnimals.remove(idAnimalB) allOtherAnimals = allAnimals eventName = "FollowZone Isolated" print("A follow B") print(eventName) followIsolatedTimeLine = EventTimeLine(None, eventName, animal, idAnimalB, None, None, loadEvent=False) print(followIsolatedTimeLine.eventNameWithId) resultIso = {} animalA = pool.animalDictionnary[animal] animalB = pool.animalDictionnary[idAnimalB] dicA = animalA.detectionDictionnary dicB = animalB.detectionDictionnary dicContactBToOtherAnimal = {} for idOtherAnimal in allOtherAnimals: dicContactBToOtherAnimal[idOtherAnimal] = contact[ idAnimalB, idOtherAnimal].getDictionnary() #dicContactBC = contact[ idAnimalB, idAnimalC ].getDictionnary() #dicContactBD = contact[ idAnimalB, idAnimalD ].getDictionnary() for t in dicB.keys(): testContactWithOtherAnimal = False for idOtherAnimal in allOtherAnimals: if (t in dicContactBToOtherAnimal[idOtherAnimal]): testContactWithOtherAnimal = True break if testContactWithOtherAnimal == True: continue ''' if ( t in dicContactBC.keys() or t in dicContactBD ): continue ''' if (t in dicA.keys()): speedA = pool.animalDictionnary[animal].getSpeed(t) speedB = pool.animalDictionnary[idAnimalB].getSpeed(t) #angleB = pool.animalList[idAnimalB].getDirection(t) angleA = pool.animalDictionnary[animal].getDirection(t) if (speedA == None or speedB == None): continue if (speedA > SPEED_THRESHOLD_LOW and speedB > SPEED_THRESHOLD_LOW): time = t angleB = pool.animalDictionnary[ idAnimalB].getDirection(time) ''' try: if( animalA.getDistanceTo( t, animalB ) > 80 ): continue except: continue ''' for time in range(t - 15, t + 1, 2): #time = t try: angleB = pool.animalDictionnary[ idAnimalB].getDirection(time) if (checkZone(dicA[t].massX, dicA[t].massY, angleA, meanSizeB, dicB[time].massX, dicB[time].massY, angleB) == True): resultIso[t] = True break except: pass followIsolatedTimeLine.reBuildWithDictionnary(resultIso) followIsolatedTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Follow Zone", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def computeProfilePairs(files, tmin, tmax, text_file, animalDic): for file in files: print(file) connection = sqlite3.connect(file) pool = AnimalPool() pool.loadAnimals(connection) genoList = [] rfidList = [] animalDic[file] = {} for animal in pool.animalDictionnary.keys(): print("computing individual animal: {}".format(animal)) rfid = pool.animalDictionnary[animal].RFID print("RFID: ".format(rfid)) animalDic[file][rfid] = {} ''' store the animal ''' # animalDic[rfid]["animal"] = pool.animalDictionnary[animal] genoA = None try: genoA = pool.animalDictionnary[animal].genotype except: pass animalDic[file][rfid][genoA] = {} genoList.append(genoA) rfidList.append(rfid) COMPUTE_TOTAL_DISTANCE = True if (COMPUTE_TOTAL_DISTANCE == True): pool.animalDictionnary[animal].loadDetection(lightLoad=True) animalDic[file][rfid][genoA][ 'distance'] = pool.animalDictionnary[animal].getDistance( tmin=tmin, tmax=tmax) for behavEvent in behaviouralEvents: print("computing individual event: {}".format(behavEvent)) behavEventTimeLine = EventTimeLineCached(connection, file, behavEvent, animal, minFrame=tmin, maxFrame=tmax) totalEventDuration = behavEventTimeLine.getTotalLength() nbEvent = behavEventTimeLine.getNumberOfEvent(minFrame=tmin, maxFrame=tmax) print("total event duration: ", totalEventDuration) animalDic[file][rfid][genoA][behavEventTimeLine.eventName + " TotalLen"] = totalEventDuration animalDic[file][rfid][genoA][behavEventTimeLine.eventName + " Nb"] = nbEvent print(behavEventTimeLine.eventName, genoA, behavEventTimeLine.idA, totalEventDuration, nbEvent) rfidPair = '{}-{}'.format(rfidList[0], rfidList[1]) animalDic[file][rfidPair] = {} pairType = '{}-{}'.format(genoList[0], genoList[1]) animalDic[file][rfidPair][pairType] = {} animalDic[file][rfidPair][pairType]['distance'] = 'NA' for behavEvent in behaviouralEvents: print("computing individual event: {}".format(behavEvent)) behavEventTimeLine = EventTimeLineCached(connection, file, behavEvent, minFrame=tmin, maxFrame=tmax) totalEventDuration = behavEventTimeLine.getTotalLength() nbEvent = behavEventTimeLine.getNumberOfEvent(minFrame=tmin, maxFrame=tmax) print("total event duration: ", totalEventDuration) animalDic[file][rfidPair][pairType][ behavEventTimeLine.eventName + " TotalLen"] = totalEventDuration animalDic[file][rfidPair][pairType][behavEventTimeLine.eventName + " Nb"] = nbEvent print(behavEventTimeLine.eventName, pairType, totalEventDuration, nbEvent) print(animalDic) print("writing...") ''' file strain sex genotype group day exp idA idB minTime maxTime ''' header = [ "file", "strain", "sex", "genotype", "group", "day", "exp", "RFID", "minTime", "maxTime" ] for name in header: text_file.write("{}\t".format(name)) ''' write event keys ''' firstAnimalKey = next(iter(animalDic[file])) print('firstAnimal: ', firstAnimalKey) genoFirstAnimal = list(animalDic[file][firstAnimalKey].keys())[0] eventDic = animalDic[file][firstAnimalKey][genoFirstAnimal] for k in eventDic.keys(): print('k: ', k) text_file.write("{}\t".format(k.replace(" ", ""))) text_file.write("\n") for rfidAnimal in animalDic[file].keys(): print(rfidAnimal) animalId = rfidAnimal animalGeno = list(animalDic[file][rfidAnimal].keys())[0] text_file.write("{}\t".format(file)) text_file.write("{}\t".format("strain")) text_file.write("{}\t".format("sex")) text_file.write("{}\t".format(animalGeno)) text_file.write("{}\t".format("group")) text_file.write("{}\t".format("day")) text_file.write("{}\t".format("exp")) text_file.write("{}\t".format(animalId)) text_file.write("{}\t".format(tmin)) text_file.write("{}\t".format(tmax)) for kEvent in animalDic[file][animalId][animalGeno].keys(): text_file.write("{}\t".format( animalDic[file][animalId][animalGeno][kEvent])) text_file.write("\n") text_file.write("\n") text_file.close() # Create a json file to store the computation jsonFileName = 'profile_unidentified_pairs.json' with open(jsonFileName, 'w') as fp: json.dump(animalDic, fp, indent=4) print("json file with acoustic measurements created for ", jsonFileName) print("done.") return animalDic
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' Animal A is stopped (built-in event): Move social: animal A is stopped and in contact with any other animal. Move isolated: animal A is stopped and not in contact with any other animal. ''' pool = AnimalPool() pool.loadAnimals(connection) isInContactSourceDictionnary = {} moveSourceTimeLine = {} for idAnimalA in range(1, pool.getNbAnimals() + 1): ''' Load source stop timeLine and revert it to get the move timeline If the animal is not detected, this will result in a move. To avoid this we mask with the detection. ''' moveSourceTimeLine[idAnimalA] = EventTimeLine(connection, "Stop", idAnimalA, minFrame=tmin, maxFrame=tmax, inverseEvent=True) detectionTimeLine = EventTimeLine(connection, "Detection", idAnimalA, minFrame=tmin, maxFrame=tmax) moveSourceTimeLine[idAnimalA].keepOnlyEventCommonWithTimeLine( detectionTimeLine) ''' load contact dictionnary with whatever animal ''' isInContactSourceDictionnary[idAnimalA] = EventTimeLineCached( connection, file, "Contact", idAnimalA, minFrame=tmin, maxFrame=tmax).getDictionnary() for idAnimalA in range(1, pool.getNbAnimals() + 1): moveSocialResult = {} moveIsolatedResult = {} ''' loop over eventlist''' for moveEvent in moveSourceTimeLine[idAnimalA].eventList: ''' for each event we seek in t and search a match in isInContactDictionnary ''' for t in range(moveEvent.startFrame, moveEvent.endFrame + 1): if t in isInContactSourceDictionnary[idAnimalA]: moveSocialResult[t] = True else: moveIsolatedResult[t] = True ''' save move ''' moveResultTimeLine = EventTimeLine(None, "Move", idAnimalA, None, None, None, loadEvent=False) moveResultTimeLine.reBuildWithDictionnary( moveSourceTimeLine[idAnimalA].getDictionnary()) moveResultTimeLine.endRebuildEventTimeLine(connection) ''' save move isolated ''' moveIsolatedResultTimeLine = EventTimeLine(None, "Move isolated", idAnimalA, None, None, None, loadEvent=False) moveIsolatedResultTimeLine.reBuildWithDictionnary(moveIsolatedResult) moveIsolatedResultTimeLine.endRebuildEventTimeLine(connection) ''' save move social ''' moveSocialResultTimeLine = EventTimeLine(None, "Move in contact", idAnimalA, None, None, None, loadEvent=False) moveSocialResultTimeLine.reBuildWithDictionnary(moveSocialResult) moveSocialResultTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Move", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def process( file ): print(file) mem = virtual_memory() availableMemoryGB = mem.total / 1000000000 print( "Total memory on computer: (GB)", availableMemoryGB ) if availableMemoryGB < 10: print( "Not enough memory to use cache load of events.") disableEventTimeLineCache() chronoFullFile = Chronometer("File " + file ) connection = sqlite3.connect( file ) # update missing fields try: connection = sqlite3.connect( file ) c = connection.cursor() query = "ALTER TABLE EVENT ADD METADATA TEXT"; c.execute( query ) connection.commit() except: print( "METADATA field already exists" , file ) BuildDataBaseIndex.buildDataBaseIndex( connection, force=False ) # build sensor data animalPool = AnimalPool( ) animalPool.loadAnimals( connection ) #animalPool.buildSensorData(file) currentT = minT try: flushEvents( connection ) while currentT < maxT: currentMinT = currentT currentMaxT = currentT+ windowT if ( currentMaxT > maxT ): currentMaxT = maxT chronoTimeWindowFile = Chronometer("File "+ file+ " currentMinT: "+ str(currentMinT)+ " currentMaxT: " + str(currentMaxT) ); processTimeWindow( connection, file, currentMinT, currentMaxT ) chronoTimeWindowFile.printTimeInS() currentT += windowT print("Full file process time: ") chronoFullFile.printTimeInS() TEST_WINDOWING_COMPUTATION = False if ( TEST_WINDOWING_COMPUTATION ): print("*************") print("************* TEST START SECTION") print("************* Test if results are the same with or without the windowing.") # display and record to a file all events found, checking with rolling idA from None to 4. Save nbEvent and total len eventTimeLineList = [] eventList = getAllEvents( connection ) file = open("outEvent"+str(windowT)+".txt","w") file.write( "Event name\nnb event\ntotal duration" ) for eventName in eventList: for animal in range( 0,5 ): idA = animal if idA == 0: idA = None timeLine = EventTimeLineCached( connection, file, eventName, idA, minFrame=minT, maxFrame=maxT ) eventTimeLineList.append( timeLine ) file.write( timeLine.eventNameWithId+"\t"+str(len(timeLine.eventList))+"\t"+str(timeLine.getTotalLength())+"\n" ) file.close() #plotMultipleTimeLine( eventTimeLineList ) print("************* END TEST") flushEventTimeLineCache() except: exc_type, exc_value, exc_traceback = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_traceback) error = ''.join('!! ' + line for line in lines) t = TaskLogger( connection ) t.addLog( error ) flushEventTimeLineCache() print( error, file=sys.stderr ) raise FileProcessException()
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): ''' Nest 3 Nest 4 Group 2 Group 3 Group 4 ''' print( "[NEST 4] : Assume that there is no occlusion, does not work with anonymous animals" ) if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax, lightLoad=True) # check if given max is more than available detection ''' maxT = pool.getMaxDetectionT() if ( tmax > maxT ): tmax = maxT ''' #pool.loadDetection( start = tmin, end = tmax ) if (len(pool.getAnimalList()) != 4): print("[NEST4 Cancelled] 4 animals are required to build nest 4.") return contact = {} for idAnimalA in range(1, 5): for idAnimalB in range(1, 5): if idAnimalA != idAnimalB: contact[idAnimalA, idAnimalB] = EventTimeLineCached( connection, file, "Contact", idAnimalA, idAnimalB, minFrame=tmin, maxFrame=tmax).getDictionnary( ) #fait une matrice de tous les contacts à deux possibles stopDictionnary = {} for idAnimalA in range(1, 5): stopDictionnary[idAnimalA] = EventTimeLineCached( connection, file, "Stop", idAnimalA, minFrame=tmin, maxFrame=tmax).getDictionnary() ''' nest3TimeLine = {} for idAnimalA in range( 1 , 5 ): nest3TimeLine = EventTimeLine( None, "Nest3" , idAnimalA, loadEvent=False ) ''' nest4TimeLine = EventTimeLine(None, "Nest4", loadEvent=False) ''' group2TimeLine = {} for idAnimalA in range( 1 , 5 ): for idAnimalB in range( 1 , 5 ): if ( idAnimalA != idAnimalB ): group2TimeLine[idAnimalA,idAnimalB] = EventTimeLine( None, "Group2" , idAnimalA , idAnimalB , loadEvent=False ) group3TimeLine = {} for idAnimalA in range( 1 , 5 ): for idAnimalB in range( 1 , 5 ): if( idAnimalA != idAnimalB ): for idAnimalC in range( 1 , 5 ): if ( idAnimalA != idAnimalC and idAnimalB != idAnimalC ): group3TimeLine[idAnimalA,idAnimalB] = EventTimeLine( None, "Group3" , idAnimalA , idAnimalB , idAnimalC, loadEvent=False ) group4TimeLine = EventTimeLine( None, "Group4" , loadEvent=False ) ''' animalList = pool.getAnimalList() result = {} for t in range(tmin, tmax + 1): isNest = False nbAnimalAtT = 0 animalDetectedList = [] for animal in animalList: if t in animal.detectionDictionnary: nbAnimalAtT += 1 animalDetectedList.append(animal) #print( str(t) + " : " + str( nbAnimalAtT ) ) if nbAnimalAtT == 0: isNest = True if not isNest: #print("TEST") graph = nx.Graph() # add nodes for animal in animalDetectedList: graph.add_node(animal) for animalA in animalDetectedList: for animalB in animalDetectedList: if animalA != animalB: # add an edge if t in contact[animalA.baseId, animalB.baseId]: graph.add_edge(animalA, animalB) # check connected components. If the biggest group gets all animal, we got a nest4 largestCC = len(max(nx.connected_components(graph), key=len)) #print( str( t ) + " : " + str ( len( largestCC ) ) ) #print( str( t ) + " : " + str ( largestCC ) + " / " + str( nbAnimalAtT ) ) if largestCC == nbAnimalAtT: # check if animals in the nest are stopped. allStoppedInBiggestGroup = True for animal in animalDetectedList: if not (t in stopDictionnary[animal.baseId]): allStoppedInBiggestGroup = False break if allStoppedInBiggestGroup: isNest = True if isNest == True: #print( "ADD PUNCTUAL") result[t] = True nest4TimeLine.reBuildWithDictionnary(result) # remove very small events nest4TimeLine.removeEventsBelowLength(2) # merge flashing events nest4TimeLine.mergeCloseEvents(3) nest4TimeLine.endRebuildEventTimeLine(connection) ''' for idAnimalA in range( 1 , 5 ): for idAnimalB in range( 1 , 5 ): if( idAnimalA == idAnimalB ): continue for idAnimalC in range( 1 , 5 ): if( idAnimalA == idAnimalC ): continue if( idAnimalB == idAnimalC ): continue for idAnimalD in range( 1 , 5 ): if( idAnimalA == idAnimalD ): continue if( idAnimalB == idAnimalD ): continue if( idAnimalC == idAnimalD ): continue eventName = "Group4" print ( eventName ) groupTimeLine = EventTimeLine( None, eventName , idAnimalA , idAnimalB , idAnimalC , idAnimalD , loadEvent=False ) result={} dicA = contact[ idAnimalA ].getDictionnary() dicB = contact[ idAnimalB ].getDictionnary() dicC = contact[ idAnimalC ].getDictionnary() dicD = contact[ idAnimalD ].getDictionnary() dicGroup2A = group2[ idAnimalA ].getDictionnary() dicGroup2B = group2[ idAnimalB ].getDictionnary() dicGroup2C = group2[ idAnimalC ].getDictionnary() dicGroup2D = group2[ idAnimalD ].getDictionnary() for t in dicA.keys(): if ( t in dicB and t in dicC and t in dicD ): if ( t in dicGroup2A or t in dicGroup2B or t in dicGroup2C or t in dicGroup2D): continue else: result[t]=True groupTimeLine.reBuildWithDictionnary( result ) groupTimeLine.endRebuildEventTimeLine(connection) ''' # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Nest4", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
def process( file ): print(file) chronoFullFile = Chronometer("File " + file ) connection = sqlite3.connect( file ) BuildDataBaseIndex.buildDataBaseIndex( connection, force=False ) # TODO: flush events, # TODO: recompute per segment of windowT. currentT = minT try: flushEvents( connection ) while currentT < maxT: currentMinT = currentT currentMaxT = currentT+ windowT if ( currentMaxT > maxT ): currentMaxT = maxT chronoTimeWindowFile = Chronometer("File "+ file+ " currentMinT: "+ str(currentMinT)+ " currentMaxT: " + str(currentMaxT) ); processTimeWindow( connection, currentMinT, currentMaxT ) chronoTimeWindowFile.printTimeInS() currentT += windowT print("Full file process time: ") chronoFullFile.printTimeInS() TEST_WINDOWING_COMPUTATION = False if ( TEST_WINDOWING_COMPUTATION ): print("*************") print("************* TEST START SECTION") print("************* Test if results are the same with or without the windowing.") # display and record to a file all events found, checking with rolling idA from None to 4. Save nbEvent and total len eventTimeLineList = [] eventList = getAllEvents( connection ) file = open("outEvent"+str(windowT)+".txt","w") file.write( "Event name\nnb event\ntotal duration" ) for eventName in eventList: for idAnimalA in range( 0,5 ): idA = idAnimalA if idA == 0: idA = None timeLine = EventTimeLineCached( connection, file, eventName, idA, minFrame=minT, maxFrame=maxT ) eventTimeLineList.append( timeLine ) file.write( timeLine.eventNameWithId+"\t"+str(len(timeLine.eventList))+"\t"+str(timeLine.getTotalLength())+"\n" ) file.close() #plotMultipleTimeLine( eventTimeLineList ) print("************* END TEST") except: exc_type, exc_value, exc_traceback = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_traceback) error = ''.join('!! ' + line for line in lines) t = TaskLogger( connection ) t.addLog( error ) print( error, file=sys.stderr ) raise FileProcessException()
def reBuildEvent(connection, file, tmin=None, tmax=None, pool=None): print("STARTING SOCIAL ESCAPE") ''' use the pool provided or create it''' if (pool == None): pool = AnimalPool() pool.loadAnimals(connection) pool.loadDetection(start=tmin, end=tmax) nbAnimal = pool.getNbAnimals() # loading all the escape of animals getAwayDico = {} for idAnimalA in range(1, nbAnimal + 1): for idAnimalB in range(1, nbAnimal + 1): if (idAnimalA == idAnimalB): continue getAwayDico[idAnimalA, idAnimalB] = EventTimeLineCached(connection, file, "Get away", idAnimalA, idAnimalB, minFrame=tmin, maxFrame=tmax) #cache mean body len twoMeanBodyLen = {} for idAnimal in range(1, nbAnimal + 1): meanBodyLength = pool.animalDictionnary[idAnimal].getMeanBodyLength() # init value twoMeanBodyLen[idAnimal] = None # set value if meanBodyLength != None: twoMeanBodyLen[idAnimal] = 2 * meanBodyLength for idAnimalA in range(1, nbAnimal + 1): for idAnimalB in range(1, nbAnimal + 1): if (idAnimalA == idAnimalB): continue eventName = "Social escape" print(eventName) socEscTimeLine = EventTimeLine(None, eventName, idAnimalA, idAnimalB, None, None, loadEvent=False) result = {} dicA = getAwayDico[idAnimalA, idAnimalB].getDictionnary() twoMeanBodyLengthB = twoMeanBodyLen[idAnimalB] for t in dicA.keys(): dist = pool.animalDictionnary[idAnimalA].getDistanceTo( t, pool.animalDictionnary[idAnimalB]) if (dist == None): continue if (dist >= 0 and dist <= twoMeanBodyLengthB): result[t] = True socEscTimeLine.reBuildWithDictionnary(result) socEscTimeLine.endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger(connection) t.addLog("Build Event Social Escape", tmin=tmin, tmax=tmax) print("Rebuild event finished.")
''' store the animal ''' animalDic[rfid]["animal"] = pool.animalDictionnary[animal] genoA = None try: genoA = pool.animalDictionnary[animal].genotype except: pass for behavEvent in behaviouralEventOneMouse: print("computing individual event: {}".format(behavEvent)) behavEventTimeLine = EventTimeLineCached(connection, file, behavEvent, animal, minFrame=tmin, maxFrame=tmax) totalEventDuration = behavEventTimeLine.getTotalLength() nbEvent = behavEventTimeLine.getNumberOfEvent(minFrame=tmin, maxFrame=tmax) print("total event duration: ", totalEventDuration) animalDic[rfid][behavEventTimeLine.eventName + " TotalLen"] = totalEventDuration animalDic[rfid][behavEventTimeLine.eventName + " Nb"] = nbEvent print(behavEventTimeLine.eventName, genoA, behavEventTimeLine.idA, totalEventDuration, nbEvent) print("writing...")
def reBuildEvent( connection, file, tmin=None, tmax=None , pool = None ): moveEventList = ['Move isolated', 'Stop isolated'] moveEventListExclusive = exclusiveEventList[-3:-1] eventPairs = {'Move isolated': 'Move isolated exclusive', 'Stop isolated': 'Stop isolated exclusive'} if ( pool == None ): pool = AnimalPool( ) pool.loadAnimals( connection ) ''' load the existing timelines for animal ''' timeLine = {} dicoContact = {} for event in moveEventList+exclusiveEventList[:-3]: timeLine[event] = {} dicoContact[event] = {} for animal in range(1, pool.getNbAnimals() + 1): timeLine[event][animal] = EventTimeLineCached( connection, file, event, animal, minFrame=tmin, maxFrame=tmax ) dicoContact[event][animal] = timeLine[event][animal].getDictionary(minFrame=tmin, maxFrame=tmax) ''' create the timelines of the different exclusive moves ''' timeLineExclusive = {} for event in moveEventListExclusive: timeLineExclusive[event] = {} for animal in range(1, pool.getNbAnimals() + 1): timeLineExclusive[event][animal] = EventTimeLine(None, event, animal, loadEvent=False) #generate the dico of the different move events and initiate the list of frames to remove from each timeline moveDicoExclusive = {} framesToRemove = {} for event in moveEventList: moveDicoExclusive[eventPairs[event]] = {} framesToRemove[eventPairs[event]] = {} for animal in range(1, pool.getNbAnimals() + 1): moveDicoExclusive[eventPairs[event]][animal] = timeLine[event][animal].getDictionary(minFrame=tmin, maxFrame=tmax) framesToRemove[eventPairs[event]][animal] = [] ########################################################################### #exclude the move and stop events where animals are in contacts for animal in range(1, pool.getNbAnimals() + 1): for moveEvent in exclusiveEventList[-3:-1]: for t in moveDicoExclusive[moveEvent][animal].keys(): for contactEvent in exclusiveEventList[:-3]: if t in dicoContact[contactEvent][animal].keys(): print('t = ', t, 'in', moveEvent, ' and in ', contactEvent) framesToRemove[moveEvent][animal].append(t) ########################################################################### # clean the dictionary of the move and stop events from frames that are overlapping with exclusive contacts for animal in range(1, pool.getNbAnimals() + 1): for moveEvent in exclusiveEventList[-3:-1]: for t in framesToRemove[moveEvent][animal]: moveDicoExclusive[moveEvent][animal].pop(t, None) ##################################################### #reduild all events based on dictionary for moveEvent in exclusiveEventList[-3:-1]: for animal in range(1, pool.getNbAnimals() + 1): timeLineExclusive[moveEvent][animal].reBuildWithDictionnary(moveDicoExclusive[moveEvent][animal]) timeLineExclusive[moveEvent][animal].endRebuildEventTimeLine(connection) # log process from lmtanalysis.TaskLogger import TaskLogger t = TaskLogger( connection ) t.addLog( "Build Event Exclusive move and stop events" , tmin=tmin, tmax=tmax ) print( "Rebuild event finished." )