diff --git a/basicalgorithm.cpp b/basicalgorithm.cpp index aeb0203..40dfb68 100644 --- a/basicalgorithm.cpp +++ b/basicalgorithm.cpp @@ -115,7 +115,7 @@ QVector BasicAlgorithm::generateFixations() { return fixations; } -QVector BasicAlgorithm::generateSaccades() { +QVector BasicAlgorithm::generateSaccades() { return saccades; } diff --git a/basicalgorithm.h b/basicalgorithm.h index f5b08a4..e3940cb 100644 --- a/basicalgorithm.h +++ b/basicalgorithm.h @@ -21,8 +21,7 @@ class BasicAlgorithm: public FixationAlgorithm { QVector generateFixations() override; - QVector generateSaccades() override; - + QVector generateSaccades() override; QString generateFixationSettings() override; private: diff --git a/controller.cpp b/controller.cpp index 5573dbf..62a12c4 100644 --- a/controller.cpp +++ b/controller.cpp @@ -433,7 +433,7 @@ void Controller::generateFixationData(QVector tasks, QString algSetting for(auto session_id : sessions) { //std::cout << "?" << std::endl; QVector session_fixations; - QVector session_saccades; + QVector session_saccades; QVector gaze_targets = idb.getGazeTargetsFromSession(session_id); QString fixation_filter_settings; diff --git a/database.cpp b/database.cpp index 0b3f739..4ef0521 100644 --- a/database.cpp +++ b/database.cpp @@ -185,6 +185,14 @@ void Database::insertGaze(QString event_time, QString session_id, QString calibr sqlite3_exec(db,query.toStdString().c_str(),NULL,0,NULL); } +//Inserts values/data into the appropriate attribute for the saccade and saccade_gaze tables +void Database::insertSaccade(QString saccade_id, QString fixation_run_id, QString start_time, QString end_time, + QString start_fixation, QString end_fixation, QString start_x, QString start_y, + QString end_x, QString end_y, QString amplitude, QString peak_velocity, + QString average_velocity, QString direction, QString duration){ + QString query=QString("INSERT INTO saccade(saccade_id,fixation_run_id,start_time,end_time,start_fixation,end_fixation,start_x,start_y,end_x,end_y,amplitude,peak_velocity,average_velocity,direction,duration) VALUES(%1,%2,%3,%4,\"%5\",\"%6\",%7,%8,%9,%10,%11,%12,%13,%14,%15);").arg(saccade_id,fixation_run_id,start_time,end_time,start_fixation,end_fixation,start_x,start_y,end_x,end_y,amplitude,peak_velocity,average_velocity,direction,duration); + sqlite3_exec(db,query.toStdString().c_str(),NULL,0,NULL); +} //issue 58 void Database::insertSaccadeGaze(QString saccade_id, QString event_time) { QString query = QString("INSERT INTO saccade_gaze(saccade_id,event_time) VALUES(\"%1\",%2);").arg(saccade_id,event_time); diff --git a/database.h b/database.h index 2bd233b..57fc41b 100644 --- a/database.h +++ b/database.h @@ -24,6 +24,7 @@ #include "gaze.h" #include +#include class Database { public: @@ -78,9 +79,9 @@ class Database { QVector> runFilterQuery(QString); void executeLongUpdateQuery(QString); + sqlite3* db; private: - sqlite3* db; QString file_path; bool open = false; }; diff --git a/fixation.cpp b/fixation.cpp index ca951f1..eda4fa7 100644 --- a/fixation.cpp +++ b/fixation.cpp @@ -71,3 +71,65 @@ void Fixation::calculateDatabaseFields() { void Fixation::print() { std::cout << fixation_event_time << "," << x << "," << y << "," << target.toUtf8().constData() << "," << source_file_line << "," << source_file_col << "," << token.toUtf8().constData() << "," << syntactic_category.toUtf8().constData() << "," << xpath.toUtf8().constData() << "," << left_pupil_diameter << "," << right_pupil_diameter << "," << duration << std::endl; } + + +/////////////////////////////// + + +Saccade::Saccade() {} + +void Saccade::calculateDatabaseFields() { + long long start_time = -1, end_time = -1; + int gaze_count = 0; + std::map candidate_targets; + for(auto gaze : gaze_vec) { + if(!gaze.isValid()) { continue; } + if(fixation_event_time == 0 || fixation_event_time > gaze.event_time) { + fixation_event_time = gaze.event_time; + } + + ++gaze_count; + + if(start_time == -1 || start_time > gaze.system_time) { + start_time = gaze.system_time; + } + if(end_time == -1 || end_time < gaze.system_time) { + end_time = gaze.system_time; + } + + + left_pupil_diameter += isnan(gaze.left_pupil_diameter) || gaze.left_pupil_diameter == -1.0 ? 0 : gaze.left_pupil_diameter; + right_pupil_diameter += isnan(gaze.right_pupil_diameter) || gaze.left_pupil_diameter == -1.0 ? 0 : gaze.right_pupil_diameter; + + QString candidate_key = gaze.gaze_target + "\t"; + candidate_key += (gaze.source_file_line == -1 ? QString("") : QString::number(gaze.source_file_line)) + "\t"; + candidate_key += (gaze.source_file_col == -1 ? QString("") : QString::number(gaze.source_file_col)) + "\t"; + candidate_key += gaze.source_token + "\t"; + candidate_key += gaze.source_token_syntatic_context + "\t"; + candidate_key += gaze.source_token_xpath + "\t"; + + if(candidate_targets.count(candidate_key) == 0) { candidate_targets.emplace(candidate_key,1); } + else { ++(candidate_targets.find(candidate_key)->second); } + } + std::pair most_frequent = std::make_pair(QString(""),0); + for(auto candidate = candidate_targets.begin(); candidate != candidate_targets.end(); ++candidate) { + if(most_frequent.first == "" || most_frequent.second < candidate->second) { most_frequent = *candidate; } + } + + QStringList fields = most_frequent.first.split("\t"); + target = fields[0] == "" ? "" : fields[0]; + source_file_line = fields[1] == "" ? -1 : fields[1].toInt(); + source_file_col = fields[2] == "" ? -1 : fields[2].toInt(); + token = fields[3] == "" ? "" : fields[3]; + syntactic_category = fields[4] == "" ? "" : fields[4]; + xpath = fields[5] == "" ? "" : fields[5]; + + left_pupil_diameter = left_pupil_diameter / double(gaze_count); + right_pupil_diameter = right_pupil_diameter / double(gaze_count); + duration = end_time - start_time; + +} + +void Saccade::print() { + std::cout << fixation_event_time << "," << x << "," << y << "," << target.toUtf8().constData() << "," << source_file_line << "," << source_file_col << "," << token.toUtf8().constData() << "," << syntactic_category.toUtf8().constData() << "," << xpath.toUtf8().constData() << "," << left_pupil_diameter << "," << right_pupil_diameter << "," << duration << std::endl; +} diff --git a/fixation.h b/fixation.h index 6ef7bce..41fd3fe 100644 --- a/fixation.h +++ b/fixation.h @@ -55,4 +55,25 @@ class Fixation { long long end_time=-1; }; +class Saccade { +public: + Saccade(); + + void calculateDatabaseFields(); + + void print(); + + // This could maybe be moved to a set if we want to ignore duplicates + std::vector gaze_vec; + double x, y, left_pupil_diameter = 0, right_pupil_diameter = 0; + int source_file_line, source_file_col, duration = 0; + long long fixation_event_time = 0; + QString target = "", syntactic_category = "", token = "", xpath = ""; + + //issue 58 - I think we add these here? + int start_x, start_y, end_x, end_y; + double amplitude, peak_velocity, avg_velocity; + double direction; +}; + #endif // FIXATION_H diff --git a/fixationalgorithm.cpp b/fixationalgorithm.cpp index 0a1c07a..c2853be 100644 --- a/fixationalgorithm.cpp +++ b/fixationalgorithm.cpp @@ -15,6 +15,7 @@ QVector& FixationAlgorithm::getFixations() { return fixations; } -QVector& FixationAlgorithm::getSaccades(){ + +QVector& FixationAlgorithm::getSaccades(){ return saccades; } diff --git a/fixationalgorithm.h b/fixationalgorithm.h index 9e8bf92..423ed83 100644 --- a/fixationalgorithm.h +++ b/fixationalgorithm.h @@ -33,8 +33,9 @@ class FixationAlgorithm QVector& getFixations(); //issue 58 - Adding virtual function for generating saccades - virtual QVector generateSaccades()=0; - QVector& getSaccades(); + virtual QVector generateSaccades()=0; + QVector& getSaccades(); + protected: virtual Fixation computeFixationEstimate(QVector)=0; @@ -43,8 +44,10 @@ class FixationAlgorithm QVector fixations; //issue 58 - a vector to store our saccades - QVector saccades; - Fixation computeSaccadeEstimate(QVector); + //Also, not sure if we'll need a saccade estimate + QVector saccades; + Saccade computeSaccadeEstimate(QVector); + }; #endif // FIXATIONALGORITHM_H diff --git a/gaze.h b/gaze.h index 2df135a..a3bc801 100644 --- a/gaze.h +++ b/gaze.h @@ -31,15 +31,16 @@ class Gaze { // void swap(Gaze&); bool isValid(); - void print(); + int db_id = -1; + int left_validation, right_validation, source_file_line = -1, source_file_col = -1; long long event_time, system_time; double x, y, left_pupil_diameter, right_pupil_diameter; QString gaze_target = "", gaze_target_type = "", - source_token = "", source_token_xpath = "", source_token_syntatic_context = ""; + source_token = "", source_token_xpath = "", source_token_syntatic_context = ""; //friend std::ostream& operator<<(std::ostream&,const Gaze&); diff --git a/idtalgorithm.cpp b/idtalgorithm.cpp index 55747b9..009d435 100644 --- a/idtalgorithm.cpp +++ b/idtalgorithm.cpp @@ -87,7 +87,8 @@ QVector IDTAlgorithm::generateFixations() { return fixations; } -QVector IDTAlgorithm::generateSaccades(){ + +QVector IDTAlgorithm::generateSaccades(){ return saccades; } diff --git a/idtalgorithm.h b/idtalgorithm.h index 5eae836..8388b31 100644 --- a/idtalgorithm.h +++ b/idtalgorithm.h @@ -22,7 +22,7 @@ class IDTAlgorithm : public FixationAlgorithm{ QVector generateFixations() override; QString generateFixationSettings() override; - QVector generateSaccades() override; + QVector generateSaccades() override; private: Fixation computeFixationEstimate(QVector) override; diff --git a/ivtalgorithm.cpp b/ivtalgorithm.cpp index 1964bfe..301743a 100644 --- a/ivtalgorithm.cpp +++ b/ivtalgorithm.cpp @@ -14,12 +14,12 @@ //Helper Functions double calculateGazeVelocity(double x1, double y1, double x2, double y2) { double vx = x1 - x2, - vy = y1 - y2; + vy = y1 - y2; double v = sqrt((vx*vx)+(vy*vy)); return v; } -//issue 58 - additonal helper functions for saccade attributes (peak velocity, average velocity, direction) + double calculateAverageVelocity(QVector gazes ){ double totalVelocity= 0; double averageVelocity=0; @@ -40,6 +40,7 @@ double calculatePeakVelocity(QVector gazes){ return peakVelocity; } + double calculateGazeDirection(QVector gazes){ double dx=0; double dy=0; @@ -107,7 +108,7 @@ QVector IVTAlgorithm::generateFixations() { } //issue 58 - creating a separate vector for saccades -QVector IVTAlgorithm::generateSaccades() { +QVector IVTAlgorithm::generateSaccades() { std::vector velocity_vector; velocity_vector.push_back(0); @@ -132,6 +133,7 @@ QVector IVTAlgorithm::generateSaccades() { } } + // Step 4 - Filter the saccade groupings-needs computeSaccadeEstimate to be implemented QVector tmp; @@ -141,13 +143,13 @@ QVector IVTAlgorithm::generateSaccades() { } else if(saccade_groups[i].second == saccade_groups[i-1].second) { tmp.push_back(saccade_groups[i].first); - Fixation sacc = computeSaccadeEstimate(tmp); - if(sacc.start_x > -1) { saccades.push_back(sacc); } + Saccade sacc = computeSaccadeEstimate(tmp); + if(sacc.start_x>-1) { saccades.push_back(sacc); } tmp.clear(); } else { - Fixation sacc = computeSaccadeEstimate(tmp); - if(sacc.start_x > -1) { saccades.push_back(sacc); } + Saccade sacc = computeSaccadeEstimate(tmp); + if(sacc.start_x>-1) { saccades.push_back(sacc); } tmp.clear(); } } @@ -158,7 +160,7 @@ Fixation IVTAlgorithm::computeFixationEstimate(QVector fixation_points) { Fixation fixation; double x_total = 0, - y_total = 0; + y_total = 0; for(auto point : fixation_points) { x_total += point.x; y_total += point.y; @@ -181,14 +183,14 @@ Fixation IVTAlgorithm::computeFixationEstimate(QVector fixation_points) { } //convert to saccadeEstimate? Will be different from above, will calculate start x and start y -Fixation IVTAlgorithm::computeSaccadeEstimate(QVector saccade_points) { - Fixation saccade; +Saccade IVTAlgorithm::computeSaccadeEstimate(QVector saccade_points) { + Saccade saccade; double dx=0; double dy=0; for(auto point : saccade_points) { - saccade.start_x=saccade_points.first().x; + saccade.start_x=saccade_points.first().x; saccade.start_y=saccade_points.first().y; saccade.end_x=saccade_points.last().x; saccade.end_y=saccade_points.last().y; diff --git a/ivtalgorithm.h b/ivtalgorithm.h index e0ebb8a..034bb78 100644 --- a/ivtalgorithm.h +++ b/ivtalgorithm.h @@ -13,6 +13,8 @@ #define IVTALGORITHM_H #include "fixationalgorithm.h" +#include "math.h" +#include "database.h" class IVTAlgorithm: public FixationAlgorithm { public: @@ -22,10 +24,11 @@ class IVTAlgorithm: public FixationAlgorithm { QVector generateFixations() override; QString generateFixationSettings() override; + //issue 58 - QVector generateSaccades() override; + QVector generateSaccades() override; - //issue 58-Connor + //issue 58-Conner //QVector gaze_vec; private: @@ -33,8 +36,9 @@ class IVTAlgorithm: public FixationAlgorithm { int velocity_threshold; int duration_ms; + Database db; //issue 58 - Fixation computeSaccadeEstimate(QVector); + Saccade computeSaccadeEstimate(QVector); }; #endif // IVTALGORITHM_H