def events_to_behavioral_sequences_all_subj(pj, obs_id: str, subjects_list: list, parameters: dict, behav_seq_separator: str) -> str: """ return the behavioral sequences for all selected subjects in obs_id Args: pj (dict): project obs_id (str): observation id subjects_list (list): list of subjects parameters (dict): parameters behav_seq_separator (str): separator of behviors in behavioral sequences Returns: str: behavioral sequences for all selected subjects in selected observation """ out = "" current_states = {i:[] for i in subjects_list} events_with_status = project_functions.events_start_stop(pj[ETHOGRAM], pj[OBSERVATIONS][obs_id][EVENTS]) for event in events_with_status: # check if event in selected behaviors if event[EVENT_BEHAVIOR_FIELD_IDX] not in parameters[SELECTED_BEHAVIORS]: continue if (event[EVENT_SUBJECT_FIELD_IDX] in subjects_list) or (event[EVENT_SUBJECT_FIELD_IDX] == "" and NO_FOCAL_SUBJECT in subjects_list): subject = event[EVENT_SUBJECT_FIELD_IDX] if event[EVENT_SUBJECT_FIELD_IDX] else NO_FOCAL_SUBJECT if event[-1] == POINT: if current_states[subject]: out += f"[{subject}]" + "+".join(current_states[subject]) + "+" + event[EVENT_BEHAVIOR_FIELD_IDX] else: out += f"[{subject}]" + event[EVENT_BEHAVIOR_FIELD_IDX] if parameters[INCLUDE_MODIFIERS]: out += "&" + event[EVENT_MODIFIER_FIELD_IDX].replace("|", "+") out += behav_seq_separator if event[-1] == START: if parameters[INCLUDE_MODIFIERS]: current_states[subject].append((f"{event[EVENT_BEHAVIOR_FIELD_IDX]}" f"{'&' if event[EVENT_MODIFIER_FIELD_IDX] else ''}" f"{event[EVENT_MODIFIER_FIELD_IDX].replace('|', ';')}")) else: current_states[subject].append(event[EVENT_BEHAVIOR_FIELD_IDX]) out += f"[{subject}]" + "+".join(sorted(current_states[subject])) out += behav_seq_separator if event[-1] == STOP: if parameters[INCLUDE_MODIFIERS]: behav_modif = (f"{event[EVENT_BEHAVIOR_FIELD_IDX]}" f"{'&' if event[EVENT_MODIFIER_FIELD_IDX] else ''}" f"{event[EVENT_MODIFIER_FIELD_IDX].replace('|', ';')}") else: behav_modif = event[EVENT_BEHAVIOR_FIELD_IDX] if behav_modif in current_states[subject]: current_states[subject].remove(behav_modif) if current_states[subject]: out += f"[{subject}]" + "+".join(sorted(current_states[subject])) out += behav_seq_separator # remove last separator (if separator not empty) if behav_seq_separator: out = out[0: -len(behav_seq_separator)] return out
def export_events(parameters, obsId, observation, ethogram, file_name, output_format): """ export events Args: parameters (dict): subjects, behaviors obsId (str): observation id observation (dict): observation ethogram (dict): ethogram of project file_name (str): file name for exporting events output_format (str): output for exporting events Returns: bool: result: True if OK else False str: error message """ total_length = f"{project_functions.observation_total_length(observation):.3f}" eventsWithStatus = project_functions.events_start_stop(ethogram, observation[EVENTS]) # check max number of modifiers max_modifiers = 0 for event in eventsWithStatus: for c in pj_events_fields: if c == "modifier" and event[pj_obs_fields[c]]: max_modifiers = max(max_modifiers, len(event[pj_obs_fields[c]].split("|"))) # media file number mediaNb = 0 if observation["type"] == MEDIA: for player in observation[FILE]: mediaNb += len(observation[FILE][player]) rows = [] # observation id rows.append(["Observation id", obsId]) rows.append([""]) # media file name if observation["type"] in [MEDIA]: rows.append(["Media file(s)"]) elif observation["type"] in [LIVE]: rows.append(["Live observation"]) else: rows.append(["?"]) rows.append([""]) if observation[TYPE] in [MEDIA]: for player in sorted(list(observation[FILE].keys())): for media in observation[FILE][player]: rows.append([f"Player #{player}", media]) rows.append([""]) # date if "date" in observation: rows.append(["Observation date", observation["date"].replace("T", " ")]) rows.append([""]) # description if "description" in observation: rows.append(["Description", utilities.eol2space(observation["description"])]) rows.append([""]) # time offset if "time offset" in observation: rows.append(["Time offset (s)", observation["time offset"]]) rows.append([""]) # independent variables if INDEPENDENT_VARIABLES in observation: rows.extend([["independent variables"], ["variable", "value"]]) for variable in observation[INDEPENDENT_VARIABLES]: rows.append([variable, observation[INDEPENDENT_VARIABLES][variable]]) rows.append([""]) # write table header col = 0 header = ["Time"] header.extend(["Media file path", "Total length", "FPS"]) header.extend(["Subject", "Behavior", "Behavioral category"]) behavioral_category = project_functions.behavior_category(ethogram) for x in range(1, max_modifiers + 1): header.append(f"Modifier {x}") header.extend(["Comment", "Status"]) rows.append(header) duration1 = [] # in seconds if observation["type"] in [MEDIA]: try: for mediaFile in observation[FILE][PLAYER1]: duration1.append(observation[MEDIA_INFO]["length"][mediaFile]) except KeyError: pass for event in eventsWithStatus: if (((event[SUBJECT_EVENT_FIELD] in parameters["selected subjects"]) or (event[SUBJECT_EVENT_FIELD] == "" and NO_FOCAL_SUBJECT in parameters["selected subjects"])) and (event[BEHAVIOR_EVENT_FIELD] in parameters["selected behaviors"])): fields = [] fields.append(utilities.intfloatstr(str(event[EVENT_TIME_FIELD_IDX]))) if observation["type"] in [MEDIA]: time_ = event[EVENT_TIME_FIELD_IDX] - observation[TIME_OFFSET] if time_ < 0: time_ = 0 if duration1: mediaFileIdx = [idx1 for idx1, x in enumerate(duration1) if time_ >= sum(duration1[0:idx1])][-1] fields.append(observation[FILE][PLAYER1][mediaFileIdx]) fields.append(total_length) # FPS try: fields.append(observation[MEDIA_INFO]["fps"][observation[FILE][PLAYER1][mediaFileIdx]]) # fps except KeyError: fields.append("NA") else: fields.append("NA") # media file fields.append("NA") # FPS if observation["type"] in [LIVE]: fields.append(LIVE) # media fields.append(total_length) # total length fields.append("NA") # FPS fields.append(event[EVENT_SUBJECT_FIELD_IDX]) fields.append(event[EVENT_BEHAVIOR_FIELD_IDX]) # behavioral category try: behav_category = behavioral_category[event[EVENT_BEHAVIOR_FIELD_IDX]] except Exception: behav_category = "" fields.append(behav_category) # modifiers if max_modifiers: modifiers = event[EVENT_MODIFIER_FIELD_IDX].split("|") while len(modifiers) < max_modifiers: modifiers.append("") for m in modifiers: fields.append(m) # comment fields.append(event[EVENT_COMMENT_FIELD_IDX].replace(os.linesep, " ")) # status fields.append(event[-1]) rows.append(fields) maxLen = max([len(r) for r in rows]) data = tablib.Dataset() data.title = utilities.safe_xl_worksheet_title(obsId, output_format) ''' if output_format in ["xls", "xlsx"]: for forbidden_char in EXCEL_FORBIDDEN_CHARACTERS: data.title = data.title.replace(forbidden_char, " ") if output_format in ["xls"]: if len(data.title) > 31: data.title = data.title[0:31] ''' for row in rows: data.append(utilities.complete(row, maxLen)) r, msg = dataset_write(data, file_name, output_format) return r, msg