Skip to content

Commit

Permalink
added db_functions
Browse files Browse the repository at this point in the history
  • Loading branch information
olivierfriard committed Jan 25, 2018
1 parent 6e7d9c0 commit a963da0
Show file tree
Hide file tree
Showing 22 changed files with 298 additions and 86 deletions.
2 changes: 1 addition & 1 deletion README.TXT
@@ -1,7 +1,7 @@
BORIS
Behavioral Observation Research Interactive Software

Copyright 2012-2017 Olivier Friard
Copyright 2012-2018 Olivier Friard

BORIS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
65 changes: 46 additions & 19 deletions boris.py
Expand Up @@ -969,6 +969,7 @@ def irr_cohen_kappa(self):
#paramPanelWindow.item.setCheckState(Qt.Unchecked)
#paramPanelWindow.lwSubjects.addItem(paramPanelWindow.item)

paramPanelWindow.resize(500, 400)
if paramPanelWindow.exec_():
selected_subjects = paramPanelWindow.selectedSubjects
include_modifiers = paramPanelWindow.cbIncludeModifiers.isChecked()
Expand Down Expand Up @@ -1000,6 +1001,11 @@ def irr_cohen_kappa(self):
if "STATE" in self.pj[ETHOGRAM][x][TYPE].upper()
and self.pj[ETHOGRAM][x]["code"] in observed_codes]

point_behaviors_codes = [self.pj[ETHOGRAM][x]["code"] for x in self.pj[ETHOGRAM]
if "POINT" in self.pj[ETHOGRAM][x][TYPE].upper()
and self.pj[ETHOGRAM][x]["code"] in observed_codes]


if not state_behaviors_codes:
QMessageBox.warning(self, programName, "No state event behaviors")
return
Expand All @@ -1023,6 +1029,7 @@ def irr_cohen_kappa(self):
self.pj[OBSERVATIONS][obsid2][EVENTS],
interval,
state_behaviors_codes,
point_behaviors_codes,
selected_subjects,
include_modifiers)

Expand Down Expand Up @@ -1962,7 +1969,18 @@ def edit_observation(self):


def check_state_events_obs(self, obsId):

"""
check state events
if no current observation check all observations
check if number is odd
Args:
obsId (str): id of observation to check
Returns:
set (bool, str): True/False, message
"""

# check if behaviors are defined as "state event"
event_types = {self.pj[ETHOGRAM][idx]["type"] for idx in self.pj[ETHOGRAM]}

Expand All @@ -1981,15 +1999,17 @@ def check_state_events_obs(self, obsId):

for behavior in sorted(set(behaviors)):
if behavior not in ethogram_behaviors:
return (False, "The behaviour <b>{}</b> does not exist more in the ethogram.<br>".format(behavior))
return (False, "The behaviour <b>{}</b> not found in the ethogram.<br>".format(behavior))
else:
if "STATE" in self.eventType(behavior).upper():
if STATE in self.eventType(behavior).upper():
flagStateEvent = True
lst, memTime = [], {}
for event in [event for event in self.pj[OBSERVATIONS][obsId][EVENTS]
if event[EVENT_BEHAVIOR_FIELD_IDX] == behavior and
event[EVENT_SUBJECT_FIELD_IDX] == subject]:

behav_modif = [event[EVENT_BEHAVIOR_FIELD_IDX], event[EVENT_MODIFIER_FIELD_IDX]]

if behav_modif in lst:
lst.remove(behav_modif)
del memTime[str(behav_modif)]
Expand All @@ -1998,7 +2018,7 @@ def check_state_events_obs(self, obsId):
memTime[str(behav_modif)] = event[EVENT_TIME_FIELD_IDX]

for event in lst:
out += ("""The behavior <b>{behavior}</b> {modifier}is not PAIRED for subject"""
out += ("""The behavior <b>{behavior}</b> {modifier} is not PAIRED for subject"""
""" "<b>{subject}</b>" at <b>{time}</b><br>""").format(
behavior=behavior,
modifier=("(modifier "+ event[1] + ") ") if event[1] else "",
Expand All @@ -2010,9 +2030,11 @@ def check_state_events_obs(self, obsId):

def check_state_events(self, mode="all"):
"""
check state events for each subject in current observation
if no current observation check all observations
check if number is odd
check state events for each subject
use check_state_events_obs function
Args:
mode (str): current: check current observation / all: ask user to select observations
"""

tot_out = ""
Expand Down Expand Up @@ -4633,19 +4655,25 @@ def eventType(self, code):

def loadEventsInDB(self, selectedSubjects, selectedObservations, selectedBehaviors):
"""
populate the db databse with events from selectedObservations, selectedSubjects and selectedBehaviors
selectedObservations: list
selectedSubjects: list
selectedBehaviors: list
populate an memory sqlite database with events from selectedObservations, selectedSubjects and selectedBehaviors
Args:
selectedObservations (list):
selectedSubjects (list):
selectedBehaviors (list):
Returns:
database cursor:
"""
db = sqlite3.connect(":memory:")

'''
if os.path.isfile("/tmp/boris_debug.sqlite"):
os.system("rm /tmp/boris_debug.sqlite")
db = sqlite3.connect("/tmp/boris_debug.sqlite")
'''

db.row_factory = sqlite3.Row
cursor = db.cursor()
cursor.execute("""CREATE TABLE events (observation TEXT,
Expand Down Expand Up @@ -7546,12 +7574,10 @@ def export_aggregated_events(self):
if "media_info" in self.pj[OBSERVATIONS][obsId]:
duration1.append(self.pj[OBSERVATIONS][obsId]["media_info"]["length"][mediaFile])
else:
#if "media_file_info" in
print("no media_info tag")
logging.info("no media_info tag for {} in observation {}" .format(mediaFile, obsId))
except:
print("error")
pass

logging.critical(sys.exc_info()[1])
QMessageBox.critical(None, programName, str(sys.exc_info()[1]), QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)

total_length = "{0:.3f}".format(self.observationTotalMediaLength(obsId))
logging.debug("media length for {0}: {1}".format(obsId, total_length))
Expand Down Expand Up @@ -8685,7 +8711,7 @@ def actionAbout_activated(self):
about_dialog.setEscapeButton(QMessageBox.Ok)

about_dialog.setInformativeText(("<b>{prog_name}</b> {ver} - {date}"
"<p>Copyright &copy; 2012-2017 Olivier Friard - Marco Gamba<br>"
"<p>Copyright &copy; 2012-2018 Olivier Friard - Marco Gamba<br>"
"Department of Life Sciences and Systems Biology<br>"
"University of Torino - Italy<br>"
"<br>"
Expand Down Expand Up @@ -11050,6 +11076,7 @@ def changedFocusSlot(self, old, now):
print(window.check_state_events_obs(observation_to_open)[1])
sys.exit()


if observation_to_open:
r = window.load_observation(observation_to_open)
if r:
Expand Down
119 changes: 119 additions & 0 deletions db_functions.py
@@ -0,0 +1,119 @@

def loadEventsInDB(self, selectedSubjects, selectedObservations, selectedBehaviors):

cursor = self.loadEventsInDB(plot_parameters["selected subjects"], selectedObservations, plot_parameters["selected behaviors"])

for subject in plot_parameters["selected subjects"]:

for behavior in plot_parameters["selected behaviors"]:

cursor.execute("SELECT occurence, modifiers, comment FROM events WHERE observation = ? AND subject = ? AND code = ? ORDER by occurence", (obsId, subject, behavior))
rows = list(cursor.fetchall())

if STATE in self.eventType(behavior).upper() and len(rows) % 2: # unpaired events
flagUnpairedEventFound = True
continue

for idx, row in enumerate(rows):

if self.pj[OBSERVATIONS][obsId]["type"] in [MEDIA]:

mediaFileIdx = [idx1 for idx1, x in enumerate(duration1) if row["occurence"] >= sum(duration1[0:idx1])][-1]
mediaFileString = self.pj[OBSERVATIONS][obsId][FILE][PLAYER1][mediaFileIdx]
fpsString = self.pj[OBSERVATIONS][obsId]["media_info"]["fps"][self.pj[OBSERVATIONS][obsId][FILE][PLAYER1][mediaFileIdx]]

if self.pj[OBSERVATIONS][obsId]["type"] in [LIVE]:
mediaFileString = "LIVE"
fpsString = "NA"

if POINT in self.eventType(behavior).upper():

if outputFormat == "sql":
out += template.format(observation=obsId,
date=self.pj[OBSERVATIONS][obsId]["date"].replace("T", " "),
media_file=mediaFileString,
total_length=total_length,
fps=fpsString,
subject=subject,
behavior=behavior,
modifiers=row["modifiers"].strip(),
event_type=POINT,
start="{0:.3f}".format(row["occurence"]),
stop=0,
comment_start=row["comment"],
comment_stop="")
else:
row_data = []
row_data.extend([obsId,
self.pj[OBSERVATIONS][obsId]["date"].replace("T", " "),
mediaFileString,
total_length,
fpsString])

# independent variables
if "independent_variables" in self.pj:
for idx_var in sorted_keys(self.pj["independent_variables"]):
if self.pj["independent_variables"][idx_var]["label"] in self.pj[OBSERVATIONS][obsId]["independent_variables"]:
row_data.append(self.pj[OBSERVATIONS][obsId]["independent_variables"][self.pj["independent_variables"][idx_var]["label"]])
else:
row_data.append("")

row_data.extend([subject,
behavior,
row["modifiers"].strip(),
POINT,
"{0:.3f}".format(row["occurence"]), # start
"NA", # stop
"NA", # duration
row["comment"],
""
])
data.append(row_data)


if STATE in self.eventType(behavior).upper():
if idx % 2 == 0:
if outputFormat == "sql":
out += template.format(observation=obsId,
date=self.pj[OBSERVATIONS][obsId]["date"].replace("T", " "),
media_file=mediaFileString,
total_length=total_length,
fps=fpsString,
subject=subject,
behavior=behavior,
modifiers=row["modifiers"].strip(),
event_type=STATE,
start="{0:.3f}".format(row["occurence"]),
stop="{0:.3f}".format(rows[idx + 1]["occurence"]),
comment_start=row["comment"],
comment_stop=rows[idx + 1]["comment"])

else:
row_data = []

row_data.extend([obsId,
self.pj[OBSERVATIONS][obsId]["date"].replace("T", " "),
mediaFileString,
total_length,
fpsString])

# independent variables
if "independent_variables" in self.pj:
for idx_var in sorted_keys(self.pj["independent_variables"]):
if self.pj["independent_variables"][idx_var]["label"] in self.pj[OBSERVATIONS][obsId]["independent_variables"]:
row_data.append(self.pj[OBSERVATIONS][obsId]["independent_variables"][self.pj["independent_variables"][idx_var]["label"]])
else:
row_data.append("")

row_data.extend([subject,
behavior,
row["modifiers"].strip(),
STATE,
"{0:.3f}".format(row["occurence"]),
"{0:.3f}".format(rows[idx + 1]["occurence"]),
"{0:.3f}".format(rows[idx + 1]["occurence"] - row["occurence"]),
row["comment"],
rows[idx + 1]["comment"]
])

data.append(row_data)
2 changes: 1 addition & 1 deletion dialog.py
Expand Up @@ -3,7 +3,7 @@
"""
BORIS
Behavioral Observation Research Interactive Software
Copyright 2012-2017 Olivier Friard
Copyright 2012-2018 Olivier Friard
This file is part of BORIS.
Expand Down
8 changes: 5 additions & 3 deletions edit_event.py
Expand Up @@ -3,7 +3,7 @@
"""
BORIS
Behavioral Observation Research Interactive Software
Copyright 2012-2017 Olivier Friard
Copyright 2012-2018 Olivier Friard
This file is part of BORIS.
Expand Down Expand Up @@ -35,16 +35,18 @@

from config import *


if QT_VERSION_STR[0] == "4":
from edit_event_ui import Ui_Form
else:
if QT_VERSION_STR[0] == "5":
from edit_event_ui5 import Ui_Form


class DlgEditEvent(QDialog, Ui_Form):

def __init__(self, log_level, parent=None):

super(DlgEditEvent, self).__init__(parent)
super().__init__(parent)
logging.basicConfig(level=log_level)
self.setupUi(self)

Expand Down
3 changes: 3 additions & 0 deletions edit_event.ui
Expand Up @@ -139,6 +139,9 @@
<property name="text">
<string>OK</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
Expand Down
4 changes: 2 additions & 2 deletions edit_event_ui.py
Expand Up @@ -2,8 +2,7 @@

# Form implementation generated from reading ui file 'edit_event.ui'
#
# Created: Tue Dec 15 12:51:27 2015
# by: PyQt4 UI code generator 4.11.2
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

Expand Down Expand Up @@ -84,6 +83,7 @@ def setupUi(self, Form):
self.pbCancel.setObjectName(_fromUtf8("pbCancel"))
self.horizontalLayout.addWidget(self.pbCancel)
self.pbOK = QtGui.QPushButton(Form)
self.pbOK.setDefault(True)
self.pbOK.setObjectName(_fromUtf8("pbOK"))
self.horizontalLayout.addWidget(self.pbOK)
self.verticalLayout.addLayout(self.horizontalLayout)
Expand Down
3 changes: 2 additions & 1 deletion edit_event_ui5.py
Expand Up @@ -2,7 +2,7 @@

# Form implementation generated from reading ui file 'edit_event.ui'
#
# Created by: PyQt5 UI code generator 5.6
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!

Expand Down Expand Up @@ -69,6 +69,7 @@ def setupUi(self, Form):
self.pbCancel.setObjectName("pbCancel")
self.horizontalLayout.addWidget(self.pbCancel)
self.pbOK = QtWidgets.QPushButton(Form)
self.pbOK.setDefault(True)
self.pbOK.setObjectName("pbOK")
self.horizontalLayout.addWidget(self.pbOK)
self.verticalLayout.addLayout(self.horizontalLayout)
Expand Down

0 comments on commit a963da0

Please sign in to comment.