def events_to_timed_behavioral_sequences(pj: dict, obs_id: str, subject: str, parameters: dict, precision: float, behav_seq_separator: str) -> str: """ return the behavioral string for subject in obsId Args: pj (dict): project obs_id (str): observation id subj (str): subject parameters (dict): parameters precision (float): time value for scan sample behav_seq_separator (str): separator of behviors in behavioral sequences Returns: str: behavioral string for selected subject in selected observation """ out = "" current_states = [] # events_with_status = project_functions.events_start_stop(pj[ETHOGRAM], pj[OBSERVATIONS][obs_id][EVENTS]) state_behaviors_codes = utilities.state_behavior_codes(pj[ETHOGRAM]) delta = Decimal(str(round(precision, 3))) out = "" t = Decimal("0.000") current = [] while t < pj[OBSERVATIONS][obs_id][EVENTS][-1][0]: ''' if out: out += behav_seq_separator ''' csbs = utilities.get_current_states_modifiers_by_subject(state_behaviors_codes, pj[OBSERVATIONS][obs_id][EVENTS], {"": {"name": subject}}, t, include_modifiers=False)[""] if csbs: if current: if csbs == current[-1]: current.append("+".join(csbs)) else: out.append(current) current = [csbs] else: current = [csbs] t += delta return out
def events_start_stop(ethogram, events): """ returns events with status (START/STOP or POINT) take consideration of subject Args: events (list): list of events Returns: list: list of events with type (POINT or STATE) """ state_events_list = utilities.state_behavior_codes( ethogram) # from utilities events_flagged = [] for event in events: time, subject, code, modifier = ( event[EVENT_TIME_FIELD_IDX], event[EVENT_SUBJECT_FIELD_IDX], event[EVENT_BEHAVIOR_FIELD_IDX], event[EVENT_MODIFIER_FIELD_IDX], ) # check if code is state if code in state_events_list: # how many code before with same subject? if (len([ x[EVENT_BEHAVIOR_FIELD_IDX] for x in events if x[EVENT_BEHAVIOR_FIELD_IDX] == code and x[EVENT_TIME_FIELD_IDX] < time and x[EVENT_SUBJECT_FIELD_IDX] == subject and x[EVENT_MODIFIER_FIELD_IDX] == modifier ]) % 2): # test if odd flag = STOP else: flag = START else: flag = POINT events_flagged.append(event + [flag]) return events_flagged
def create_behavior_binary_table(pj: dict, selected_observations: list, parameters_obs: dict, time_interval: float) -> dict: """ create behavior binary table Args: pj (dict): project dictionary selected_observations (list): list of selected observations parameters_obs (dict): dcit of parameters time_interval (float): time interval (in seconds) Returns: dict: dictionary of tablib dataset """ results_df = {} state_behavior_codes = [ x for x in utilities.state_behavior_codes(pj[ETHOGRAM]) if x in parameters_obs[SELECTED_BEHAVIORS] ] point_behavior_codes = [ x for x in utilities.point_behavior_codes(pj[ETHOGRAM]) if x in parameters_obs[SELECTED_BEHAVIORS] ] if not state_behavior_codes and not point_behavior_codes: return {"error": True, "msg": "No state events selected"} for obs_id in selected_observations: if obs_id not in results_df: results_df[obs_id] = {} for subject in parameters_obs[SELECTED_SUBJECTS]: # extract tuple (behavior, modifier) behav_modif_list = [ (idx[2], idx[3]) for idx in pj[OBSERVATIONS][obs_id][EVENTS] if idx[1] == (subject if subject != NO_FOCAL_SUBJECT else "") and idx[2] in parameters_obs[SELECTED_BEHAVIORS] ] # extract observed subjects NOT USED at the moment observed_subjects = [ event[EVENT_SUBJECT_FIELD_IDX] for event in pj[OBSERVATIONS][obs_id][EVENTS] ] # add selected behavior if not found in (behavior, modifier) if not parameters_obs[EXCLUDE_BEHAVIORS]: #for behav in state_behavior_codes: for behav in parameters_obs[SELECTED_BEHAVIORS]: if behav not in [x[0] for x in behav_modif_list]: behav_modif_list.append((behav, "")) behav_modif_set = set(behav_modif_list) observed_behav = [(x[0], x[1]) for x in sorted(behav_modif_set)] if parameters_obs[INCLUDE_MODIFIERS]: results_df[obs_id][subject] = tablib.Dataset( headers=["time"] + [ f"{x[0]}" + f" ({x[1]})" * (x[1] != "") for x in sorted(behav_modif_set) ]) else: results_df[obs_id][subject] = tablib.Dataset( headers=["time"] + [x[0] for x in sorted(behav_modif_set)]) if subject == NO_FOCAL_SUBJECT: sel_subject_dict = {"": {SUBJECT_NAME: ""}} else: sel_subject_dict = dict([ (idx, pj[SUBJECTS][idx]) for idx in pj[SUBJECTS] if pj[SUBJECTS][idx][SUBJECT_NAME] == subject ]) row_idx = 0 t = parameters_obs[START_TIME] while t < parameters_obs[END_TIME]: # state events current_states = utilities.get_current_states_modifiers_by_subject_2( state_behavior_codes, pj[OBSERVATIONS][obs_id][EVENTS], sel_subject_dict, t) # point events current_point = utilities.get_current_points_by_subject( point_behavior_codes, pj[OBSERVATIONS][obs_id][EVENTS], sel_subject_dict, t, time_interval) cols = [float(t)] # time for behav in observed_behav: if behav[0] in state_behavior_codes: cols.append( int(behav in current_states[list( current_states.keys())[0]])) if behav[0] in point_behavior_codes: cols.append(current_point[list( current_point.keys())[0]].count(behav)) results_df[obs_id][subject].append(cols) t += time_interval row_idx += 1 return results_df
def test_empty_ethogram(self): r = utilities.state_behavior_codes({}) assert r == []
def test_1(self): pj_float = json.loads(open("files/test.boris").read()) r = utilities.state_behavior_codes(pj_float["behaviors_conf"]) # print(r) assert r == ['s', 'r', 'm']