-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path10_qc_checks.html
297 lines (213 loc) · 11.5 KB
/
10_qc_checks.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Check for QC</title>
<script src = "../dissimilarity_test/extra_functions/jquery-3.4.1.js" type="text/javascript"></script>
<script src="./jspsych-6.1.0/jspsych.js"></script>
<link href="./jspsych-6.1.0/css/jspsych.css" rel="stylesheet" type="text/css"></link>
<script src="jatos.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src='./jspsych-6.1.0/plugins/jspsych-survey-text.js'></script>
<script src="./extra_functions/helper_functions.js"> </script>
<script src='./extra_functions/lodash.js'></script>
</head>
<body></body>
<script>
jatos.onLoad(function() {
// What phase is this?
let [curr_phase,phase_string,curr_session,curr_global_trial] = getPhaseAndSession()
// //////////////////////////////////// FUNCTIONS /////////////////////////////////////////////
// Updating batch data to reflect failure
const batch_data_reflect_failure = function(){
if (jatos.studySessionData.use_batch_data){
// Update the batch data to reflect that this ptp failed.
var batchData = jatos.batchSession.getAll();
// Find the condition
for (i = 0; i < batchData.length; i++){
if(batchData[i].congruency == jatos.studySessionData.inputData.congruency &&
batchData[i].phase_1_concept == jatos.studySessionData.inputData.concepts.phase_1.concept_space &&
batchData[i].phase_2_concept == jatos.studySessionData.inputData.concepts.phase_2.concept_space &&
JSON.stringify(batchData[i].phase_1_arrangement) ==
JSON.stringify(jatos.studySessionData.inputData.basic_parameters.targetPoints.phase_1) &&
JSON.stringify(batchData[i].phase_2_arrangement) ==
JSON.stringify(jatos.studySessionData.inputData.basic_parameters.targetPoints.phase_2)){
batchData[i].n_ptp_fail ++;
batchData[i].n_ptp_pass_or_ongoing --;
batchData[i].n_ptp_needed ++;
}
}
// Update the batch data
jatos.batchSession.setAll(batchData);
} // if use_batch_data
}
// Simulate data to make sure our scripts work correctly
const simulate_data = function(last_session_data,conditionToSimulate){
if (!jatos.studySessionData.latestFinishedComponentTitle.includes('practice')){
// rt_min_speed and rt_min_perc:
if (conditionToSimulate == 'rt'){
// get the criteria locally
let rt_min_speed = jatos.studySessionData.qc_criteria.rt_min_speed
let rt_min_perc = jatos.studySessionData.qc_criteria.rt_min_perc
// How many to change?
let nChange = Math.round(last_session_data.length * rt_min_perc / 100) + 1
for (iTrial=0; iTrial<nChange; iTrial++){
last_session_data[iTrial].rt = rt_min_speed - 5
}
} else if (conditionToSimulate == 'uniform_resp_perc'){
// Get criteria locally
uniform_resp_perc = jatos.studySessionData.qc_criteria.uniform_resp_perc
let nChange = Math.round(last_session_data.length * uniform_resp_perc / 100) + 1
for (iTrial=0; iTrial<nChange; iTrial++){
last_session_data[iTrial].key_press = '49'
}
for (iTrial=nChange; iTrial<last_session_data.length; iTrial++){
last_session_data[iTrial].key_press = '50'
}
} else if (conditionToSimulate == 'perc_max_missed'){
// get the criteria locally
let perc_max_missed = jatos.studySessionData.qc_criteria.perc_max_missed
// How many to change?
let nChange = Math.round(last_session_data.length * perc_max_missed / 100) + 1
for (iTrial=0; iTrial<nChange; iTrial++){
last_session_data[iTrial].rt = null
}
}
}
return last_session_data
};
// Define a function to do the checks
const session_qc_check = function(last_session_data){
// 1. Not too many missed trials
let n_missed_trials = last_session_data.filter(item => item.rt==null).length
let perc_missed_trials = n_missed_trials * 100 / last_session_data.length
if (perc_missed_trials >= jatos.studySessionData.qc_criteria.perc_max_missed){
jatos.studySessionData.qc_status.perc_max_misses_pass = false
jatos.studySessionData.qc_status.global_pass = false
}
// 2. Not too many fast trials
let n_fast_trials = last_session_data.filter(item => item.rt < jatos.studySessionData.qc_criteria.rt_min_speed).length
let perc_fast_trials = n_fast_trials * 100 / last_session_data.length
if (perc_fast_trials >= jatos.studySessionData.qc_criteria.rt_min_perc){
jatos.studySessionData.qc_status.rt_pass = false
jatos.studySessionData.qc_status.global_pass = false
}
// 3. Not too many similar responses
// Get the bin counts
let bin_counts = [];
let responded_trials = last_session_data.filter(item => item.rt !== null);
for (iElement = 0; iElement < jatos.studySessionData.inputData.choices.length; iElement++){
bin_counts[iElement] = responded_trials.filter(item => item.key_press == ['49','50'][iElement]).length;
}
let max_count = Math.max(...bin_counts);
let max_perc = max_count * 100 / responded_trials.length
if (max_perc >= jatos.studySessionData.qc_criteria.uniform_resp_perc){
jatos.studySessionData.qc_status.global_pass = false;
jatos.studySessionData.qc_status.uniform_resp_perc_pass = false;
}
// 4. If session >= preset_amount, check better than chance
if (curr_session >= jatos.studySessionData.qc_criteria.min_perf_check_ses){
// Get the current performance
let curr_running_perf = last_session_data[last_session_data.length-1].running_perf
let n_targets_above_chance =
curr_running_perf.filter(item => item >
jatos.studySessionData.qc_criteria.min_perf_check_perc).length
if (n_targets_above_chance < jatos.studySessionData.inputData.basic_parameters.nTargets) {
jatos.studySessionData.qc_status.global_pass = false;
jatos.studySessionData.qc_status.min_perf_pass = false;
}
}
// Has the ptp failed?
if (jatos.studySessionData.qc_status.global_pass == false){
// Update batch data to reflect failure
batch_data_reflect_failure();
jatos.studySessionData.progress_state = 'qc_failed_' + phase_string
} else {
// So didn't fail
// Check, if exceeded the performance, then continue to the next step
let all_targets_learned = last_session_data[last_session_data.length-1].running_perf.every(
item => item >= jatos.studySessionData.training_criterion
)
// Also check that minimum number of sessions have been done.
if (all_targets_learned && curr_session >= jatos.studySessionData.qc_criteria.min_training_sess) {
if (curr_phase == jatos.studySessionData.max_phases){
jatos.studySessionData.progress_state = 'finished_training'
} else {
jatos.studySessionData.progress_state = 'advance_phase'
}
} else {
// So, they haven't failed but havent learned or havent finished the minimum number of sessions.
// Check if they've done too many sessions, if not then advance a session
if (jatos.studySessionData.session_counter[phase_string] == jatos.studySessionData.qc_criteria.max_training_sess){
jatos.studySessionData.qc_status.max_training_sess_pass = false
jatos.studySessionData.qc_status.global_pass = false
jatos.studySessionData.progress_state = 'qc_failed_' + phase_string
// Update batch data to reflect failure
batch_data_reflect_failure();
} else {
jatos.studySessionData.progress_state = 'advance_session'
}
}
} // global pass fail? if/else section
}; // end of the function session_qc_check
// ////////////////////////////////////////////// START CHECKS //////////////////////////////////////////////////////////////
// Get the latest data
let last_session_data = jatos.studySessionData.last_session_data
// If we are simulating data:
if (jatos.studySessionData.simulate_data){
last_session_data = simulate_data(last_session_data,jatos.studySessionData.simulate_condition)
}
if (curr_phase == 1){
// Are we checking practice trials?
if (jatos.studySessionData.latestFinishedComponentTitle.includes('practice')){
// 1. Check instructions weren't breezed through too fast
let viewing_history = JSON.parse(jatos.studySessionData.outputData.instructions_results.phase_1.view_history)
// How many pages are there?
let all_page_idxs = viewing_history.map(item => item.page_index)
let max_pages = Math.max(...all_page_idxs)
// For each page that was visited,
// make sure they spent at least certain amount. If not, fail the QC
for (iP=0; iP<=max_pages; iP++){
// Get all the pages with this index
let curr_pages = viewing_history.filter( item => item.page_index == iP)
// Sum the total viewing time
let iTotalTime = curr_pages.map(item => item.viewing_time).reduce((acc,item) => acc + item, 0)
if (iTotalTime < jatos.studySessionData.qc_criteria.min_time_instruct){
jatos.studySessionData.qc_status.global_pass = false
jatos.studySessionData.qc_status.min_time_instruct_pass = false
jatos.studySessionData.progress_state = 'qc_failed_instructions'
}
};
// 2. Check RTs not too low. Also checks that not all trials were missed
let rt_speed_pass_practice = last_session_data.some(item => item.rt > jatos.studySessionData.qc_criteria.rt_min_speed)
// record in the jatos object
jatos.studySessionData.qc_status.practice_pass = rt_speed_pass_practice
if (!rt_speed_pass_practice){
// Record global pass failure
jatos.studySessionData.qc_status.global_pass = false
jatos.studySessionData.progress_state = 'qc_failed_practice'
}
// So, did they fail here?
if (jatos.studySessionData.qc_status.global_pass == false){
// Update batch data to reflect failure
batch_data_reflect_failure();
}
} else {
// //////// Checking real sessions of phase 1 ////////////
// ////////////////////////////////////////////////////////
// This function will check all the qc criteria, and determine what to do next
session_qc_check(last_session_data)
} // Checking the real sessions section
} else {
// So its phase 2+ //////////////////////////////////////////////////////////////////////////////////////////
// This function will check all the qc criteria, and determine what to do next
session_qc_check(last_session_data)
} // phase bracket
// Submit the data and move on
jatos.submitResultData("[qc_start---" + JSON.stringify(jatos.studySessionData) +
"---qc_end]", function(){
jatos.startComponentByPos(jatos.studySessionData.script_comp_pos.transition);
});
}); // jatos IFFY
</script>
</html>