Beispiel #1
0
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
Beispiel #2
0
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
def events_to_behavioral_sequences(pj,
                                   obs_id: str,
                                   subj: str,
                                   parameters: dict,
                                   behav_seq_separator: str) -> str:
    """
    return the behavioral sequence (behavioral string) for subject in obsId

    Args:
        pj (dict): project
        obs_id (str): observation id
        subj (str): subject
        parameters (dict): parameters
        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])

    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] == subj or (subj == NO_FOCAL_SUBJECT and event[EVENT_SUBJECT_FIELD_IDX] == ""):

            if event[-1] == POINT:
                if current_states:
                    out += "+".join(current_states) + "+" + event[EVENT_BEHAVIOR_FIELD_IDX]
                else:
                    out += 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.append("{}{}{}".format(event[EVENT_BEHAVIOR_FIELD_IDX],
                                                          "&" if event[EVENT_MODIFIER_FIELD_IDX] else "",
                                                          event[EVENT_MODIFIER_FIELD_IDX].replace("|", ";")))
                else:
                    current_states.append(event[EVENT_BEHAVIOR_FIELD_IDX])

                out += "+".join(sorted(current_states))

                out += behav_seq_separator

            if event[-1] == STOP:

                if parameters[INCLUDE_MODIFIERS]:
                    behav_modif = "{}{}{}".format(event[EVENT_BEHAVIOR_FIELD_IDX],
                                                  "&" if event[EVENT_MODIFIER_FIELD_IDX] else "",
                                                  event[EVENT_MODIFIER_FIELD_IDX].replace("|", ";"))
                else:
                    behav_modif = event[EVENT_BEHAVIOR_FIELD_IDX]
                if behav_modif in current_states:
                    current_states.remove(behav_modif)

                if current_states:
                    out += "+".join(sorted(current_states))

                    out += behav_seq_separator

    # remove last separator (if separator not empty)
    if behav_seq_separator:
        out = out[0: -len(behav_seq_separator)]

    return out
Beispiel #4
0
def events_to_behavioral_sequences(pj, obs_id: str, subj: str,
                                   parameters: dict,
                                   behav_seq_separator: str) -> str:
    """
    return the behavioral sequence (behavioral string) for subject in obsId

    Args:
        pj (dict): project
        obs_id (str): observation id
        subj (str): subject
        parameters (dict): parameters
        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])

    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] == subj or (
                subj == NO_FOCAL_SUBJECT
                and event[EVENT_SUBJECT_FIELD_IDX] == ""):

            if event[-1] == POINT:
                if current_states:
                    out += "+".join(
                        current_states) + "+" + event[EVENT_BEHAVIOR_FIELD_IDX]
                else:
                    out += 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.append("{}{}{}".format(
                        event[EVENT_BEHAVIOR_FIELD_IDX],
                        "&" if event[EVENT_MODIFIER_FIELD_IDX] else "",
                        event[EVENT_MODIFIER_FIELD_IDX].replace("|", ";")))
                else:
                    current_states.append(event[EVENT_BEHAVIOR_FIELD_IDX])

                out += "+".join(sorted(current_states))

                out += behav_seq_separator

            if event[-1] == STOP:

                if parameters[INCLUDE_MODIFIERS]:
                    behav_modif = "{}{}{}".format(
                        event[EVENT_BEHAVIOR_FIELD_IDX],
                        "&" if event[EVENT_MODIFIER_FIELD_IDX] else "",
                        event[EVENT_MODIFIER_FIELD_IDX].replace("|", ";"))
                else:
                    behav_modif = event[EVENT_BEHAVIOR_FIELD_IDX]
                if behav_modif in current_states:
                    current_states.remove(behav_modif)

                if current_states:
                    out += "+".join(sorted(current_states))

                    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 = "{0:.3f}".format(project_functions.observation_total_length(observation))

    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(["Player #{0}".format(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("Modifier {}".format(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 = obsId
    # check if worksheet name will be > 31 char
    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