Generate
}); function processData(data) { DATA = data; console.log(data); let questionLabels = new Set(); Q = questionLabels; let numChoicesPerQuestion = []; let results = []; let allSubjects = []; let subjectIndex = 0; let btsAllEndorsing = []; let btsAllPrediction = []; let resultsWithBTS = []; let totalAnswerChoices = 0; let doBTSCalc = false; // "2021/05/12 16:18:00" for(let i = 0; i < data.tests.length; i++) { let subject = data.tests[i].subjects[0]; allSubjects.push(subject.uid); let isAMT = subject.amt ? true : false; if(data.tests[i].submissions.length > 0) { let answers = data.tests[i].submissions[0].val; let result = {}; if(isAMT) { result.workerID = answers[answers.length - 1]; result.assignmentID = answers[answers.length - 2]; answers = answers.slice(0, answers.length - 2); } let chosenAnswers = {}; for(let j = 0; j < answers.length; j++) { let currQuestionLabel = answers[j].questionLabel; chosenAnswers[currQuestionLabel] = answers[j].answerLabel; if (answers[j].btsPercentageList) { doBTSCalc = true; } if (doBTSCalc) { let currNumChoices = answers[j].numChoices; let btsSubjectEndorsing = []; let btsSubjectPrediction = []; totalAnswerChoices = totalAnswerChoices + currNumChoices; questionLabels.add(currQuestionLabel); numChoicesPerQuestion[currQuestionLabel] = currNumChoices; btsSubjectEndorsing[currQuestionLabel] = answers[j].btsEndorsingList; btsSubjectPrediction[currQuestionLabel] = answers[j].btsPercentageList; } } if (doBTSCalc) { btsAllEndorsing.push(btsSubjectEndorsing); btsAllPrediction.push(btsSubjectPrediction); console.log(btsAllEndorsing); console.log(btsAllPrediction); } result.answers = chosenAnswers; result.isAMT = isAMT; result.subjectID = subject.uid; result.date = data.tests[i].date; result.testID = data.tests[i].id; results.push(result); subjectIndex++; } } console.log(results); if (!doBTSCalc) { let headers = ["Test ID", "Test Date", "Subject ID", "AMT", "Worker ID", "Assignment ID"]; let arrayLabels = Array.from(questionLabels); headers = headers.concat(arrayLabels); for(let label in questionLabels) { console.log(label); headers.push(label); } let rows = [headers]; for(let i = 0; i < results.length; i++) { let r = results[i]; let row = [r.testID, r.date, r.subjectID, r.isAMT, r.workerID, r.assignmentID]; for(let a = 0; a < arrayLabels.length; a++) { let label = arrayLabels[a]; row.push(results[i].answers[label]); } rows.push(row.join(",")); } } else { let numSubjects = allSubjects.length; let btsTotalNumEndorsing = []; let btsTotalOfPredictions = []; let btsTotalNumEndorsingQuestion = []; let btsTotalOfPredictionsQuestion = []; let btsFractionEndorsing = []; let btsAvgPrediction = []; let btsFractionEndorsingQuestion = []; let btsAvgPredictionQuestion = []; for(let label in questionLabels) { let currNumChoices = numChoicesPerQuestion[label].length; for(let i = 0; i < currNumChoices; i++) { btsTotalNumEndorsingQuestion[i] = 0; btsTotalOfPredictionsQuestion[i] = 0; for(let j = 0; j < numSubjects; j++) { btsTotalNumEndorsingQuestion[i] = btsTotalNumEndorsingQuestion[i] + btsAllEndorsing[j][label][i]; btsTotalOfPredictionsQuestion[i] = btsTotalOfPredictionsQuestion[i] + btsAllPrediction[j][label][i]; } } btsTotalNumEndorsing[label] = btsTotalNumEndorsingQuestion; btsTotalNumPrediction[label] = btsTotalNumPredictionQuestion; for(let i = 0; i < currNumChoices; i++) { btsFractionEndorsingQuestion[i] = 0; btsAvgPredictionsQuestion[i] = 0; if (numSubjects > 0) { btsFractionEndorsingQuestion[i] = btsTotalNumEndorsingQuestion[i] / numSubjects; btsAvgPredictionQuestion[i] = btsAvgPredictionQuestion[i] / numSubjects; } } btsFractionEndorsing[label] = btsFractionEndorsingQuestion; btsAvgPrediction[label] = btsAvgPredictionQuestion; } let btsInformationScoreAnsChoice = []; let btsPredictionScoreAnsChoice = []; let currAnswerChoice = 0; for(let i = 0; i < numSubjects; i++) { for(let label in questionLabels) { let currInformationScore = 0; let currPredictionScore = 0; let currNumChoices = numChoicesPerQuestion[label].length; for(let j = 0; j < currNumChoices; j++) { let currSubjectEndorsing = btsAllEndorsing[i][label][j]; let currSubjectPrediction = btsAllPrediction[i][label][j]; let currFractionEndorsing = btsFractionEndorsing[label][j]; let currAvgPrediction = btsAvgPrediction[label][j]; if (currAvgPrediction > 0) { currInformationScore = currSubjectEndorsing * (Math.log10(currFractionEndorsing / currAvgPrediction)); } if (currAvgFractionEndorsing > 0) { currPredictionScore = currFractionEndorsing * (Math.log10(currSubjectPrediction / currFractionEndorsing)); } } btsInformationScoreAnsChoice[currAnswerChoice] = currInformationScore; btsPredictionScoreAnsChoice[currAnswerChoice] = currPredictionScore; currAnswerChoice++; } let currInformationScore = 0; let currPredictionScore = 0; let currBTSFinalScore = 0; let choicePredictionLabels = []; for(let j = 0; j < numAnswerChoices; j++) { currInformationScore = currInformationScore + btsInformationScoreAnsChoice[j]; currPredictionScore = currPredictionScore + btsPredictionScoreAnsChoice[j]; } currBtsFinalScore = currInformationScore + currPredictionScore; let resultWithBTS = results[i]; resultWithBTS.informationScore = currInformationScore; resultWithBTS.predictionScore = currPredictionScore; resultWithBTS.finalBTSScore = currBTSFinalScore; // fix this to get percentages output resultWithBTS.predictionScore = currPredictionScore; for(let k = 0; k < numAnswerChoices; k++) { let choicePredictionLabel = 'choice' + k.toString() + 'Prediction'; resultsWithBTS[choicePredictionLabel] = btsAllPrediction[i][label][k]; } resultsWithBTS.push(resultWithBTS); } let headers = ["Test ID", "Test Date", "Subject ID", "AMT", "Worker ID", "Assignment ID", "Information Score", "Prediction Score", "Final BTS Score"]; let arrayLabels = Array.from(questionLabels); headers = headers.concat(arrayLabels); for(let label in questionLabels) { console.log(label); headers.push(label); for(let i = 0; i < numChoicesPerQuestion[label].length; i++) { choiceStr = i.toString(); headers.push(label + choiceStr + ' Percentage Prediction'); } } let rows = [headers]; for(let i = 0; i < resultsWithBTS.length; i++) { let r = resultsWithBTS[i]; let row = [r.testID, r.date, r.subjectID, r.isAMT, r.workerID, r.assignmentID, r.informationScore, r.predictionScore, r.finalBTSScore]; for(let a = 0; a < arrayLabels.length; a++) { let label = arrayLabels[a]; row.push(resultsWithBTS[i].answers[label]); // fix this for for(let b = 0; b < numChoicesPerQuestion[label].length; b++) { let choicePredictionLabel = 'choice' + b.toString() + 'Prediction'; row.push(resultsWithBTS[choicePredctionLabel]); } } rows.push(row.join(",")); } } let csv = rows.join("\n"); const blob = new Blob([csv], { type: 'text/csv' }); const downloadLink = downloadBlob(blob, 'records.csv'); // Set the title and classnames of the link downloadLink.title = 'Export Records as CSV'; downloadLink.classList.add('btn-link', 'download-link'); // Set the text content of the download link downloadLink.textContent = 'Export Records'; // Attach the link to the DOM //document.body.appendChild(downloadLink); $("#loading").text(""); $("#downloadLinks").html(""); $("#downloadLinks").append(downloadLink); let metadata = "Test Run\n"; metadata += "Experiment: Coinbase Study\n"; metadata += `Start Date: ${$("#startDate").val()}\nEnd Date: ${$("#endDate").val()}\n\n`; metadata += `Results Downloaded: ${rows.length - 1}\n\n`; metadata += 'Columns:\n'; metadata += 'Label: Test ID\nUID for the test run\n\nTest Date\nDate test was conducted\n\nSubject ID\nUID for the subject\n\nAMT\nTRUE if Mturk worker, FALSE otherwise\n\nWorker ID\nWorker ID of AMT is TRUE, blank otherwise\n\nAssignment ID\nUID of the AMT assignment, if applicable\n\n'; for(let a = 0; a < arrayLabels.length; a++) { let qText = ""; let aTexts = []; for(let x = 0; x < CONFIG.length; x++) { if(CONFIG[x].questionLabel === arrayLabels[a]) { qText = CONFIG[x].questionText; for(let y = 0; y < CONFIG[x].answerChoices.length; y++) { aTexts.push(`${CONFIG[x].answerChoices[y]} = ${y}`); } } } let aText = aTexts.join(", "); metadata += `Label: ${arrayLabels[a]}\nQuestion: ${qText}\nAnswers: ${aText}\n\n`; } console.log(metadata); const mblob = new Blob([metadata], { type: 'text/plain' }); const mdownloadLink = downloadBlob(mblob, 'metadata.txt'); // Set the title and classnames of the link mdownloadLink.title = 'Export Metadata'; mdownloadLink.classList.add('btn-link', 'download-link'); // Set the text content of the download link mdownloadLink.textContent = 'Export Metadata'; $("#downloadLinks").append('
'); $("#downloadLinks").append(mdownloadLink); } // credit to https://blog.logrocket.com/programmatic-file-downloads-in-the-browser-9a5186298d5c/ function downloadBlob(blob, filename) { // Create an object URL for the blob object const url = URL.createObjectURL(blob); // Create a new anchor element const a = document.createElement('a'); // Set the href and download attributes for the anchor element // You can optionally set other attributes like `title`, etc // Especially, if the anchor element will be attached to the DOM a.href = url; a.download = filename || 'download'; // Click handler that releases the object URL after the element has been clicked // This is required for one-off downloads of the blob content const clickHandler = () => { setTimeout(() => { URL.revokeObjectURL(url); this.removeEventListener('click', clickHandler); }, 150); }; // Add the click event listener on the anchor element // Comment out this line if you don't want a one-off download of the blob content a.addEventListener('click', clickHandler, false); // Programmatically trigger a click on the anchor element // Useful if you want the download to happen automatically // Without attaching the anchor element to the DOM // Comment out this line if you don't want an automatic download of the blob content //a.click(); // Return the anchor element // Useful if you want a reference to the element // in order to attach it to the DOM or use it in some other way return a; }