source("http://logfsm.com/latest")
Datenerhebung: Datenaufbereitung / Data Collection: Data Post-Processing
Datenaufbereitung
Daten werden vom IRTlib Player in Rohdatenarchiven pro Session (d.h. pro Testdurchführung mit einer Studie) gespeichert. Die Rohdatenarchive sind ZIP-Archive, deren Dateinamen dem Benutzernamen oder dem Universally Unique Identifier (UUID) entsprechen. Abweichungen von diesem Schema sind möglich, wenn zum Zeitpunkt der Speicherung bereits ein Rohdatenarchiv mit diesem Dateinamen vorhanden war. In diesem Fall werden die Daten vim IRTlib Player nicht überschrieben, sondern es wird ein Suffix _1
, _2
, … angehängt, bis der Dateiname verwendbar ist.
- Offline IRTlib Player: Wenn nicht anders konfiguriert wurde, werden die Ergebnisdaten im Verzeichnis
Temp/{Studien-Name}/Results
gespeichert. Die Rohdatenarchive werden erstellt, wenn eine Session beendet, d.h. die letzte definierte CBA ItemBuilder-Task mitNEXT_TASK
verlassen wird. Erst wenn die Rohdatenarchive erstellt wurden, ist ein Fortsetzen der angefangenen Session, wie es beispielsweise bei einem Computerabsturz notwendig sein kann, nicht mehr möglich.
Analog verhält es sich auch, wenn die Offline-Version des IRTlib Player als lokaler Server eingesetzt wird. Die Rohdatenarchive werden nach der Testbearbeitung im Verzeichnis
Temp/{Studien-Name}/Results
gespeichert.
Die Sammlung von Daten aus den Offline IRTlib Playern entspricht dem Einsammeln der Rohdatenarchive, die auf den verschiedenen Geräten erhoben werden.
Da die Offline IRTlib Player untereinander nicht in Verbindung stehen, können - je nach Loginmodus - identische Anmeldedaten in verschiedenen IRTlib Playern parallel erstellt werden. Nach einer Datenerhebung müssen die Rohdatenarchive deshalb mit Sorgfalt zusammengefügt und ggf. durch Unterordner getrennt werden.
- Online IRTlib Player: Der Online-Player sammelt die Daten, wenn nicht anders konfiguriert, in dem Volume, welches für die Ergebnisdaten konfiguriert ist (vgl.
/app/results
indocker-compse.yml
-File). Jede Session wird dort in einem separaten Unterverzeichnis gespeichert und kann von Administratoren, die Zugriff auf das Volume haben (!), heruntergeladen werden.
Wenn ein API-key für den Datenzugriff definiert ist, kann der Download der Ergebnisdaten auch über das R-Paket LogFSM erfolgen.
Datenabruf mit LogFSM
Dazu kann mit folgendem Aufruf zunächst (einmalig) das R-Paket installiert werden:
Danach ist der Download der Rohdatenarchive mit folgendem R-Skript möglich:
library(LogFSM)
if (!dir.exists(paste0(getwd(),"/in/")))
dir.create(paste0(getwd(),"/in/"))
if (!dir.exists(paste0(getwd(),"/out/")))
dir.create(paste0(getwd(),"/out/"))
<- "(your secret key)"
SECRET_KEY <- "(your API-URL)"
API_URL
::TransformToUniversalLogFormat(inputfolders = paste0(getwd(),"/in/"),
LogFSMinputformat = "irtlibv01a",
zcsvoutput = paste0(getwd(),"/out/data_csv.zip"),
stataoutput = paste0(getwd(),"/out/data_dta.zip"),
spssoutput = paste0(getwd(),"/out/data_sav.zip"),
key = SECRET_KEY,
web = API_URL,
outputtimestampformatstring="dd.MM.yyyy HH:mm:ss.fff")
<- read.csv(unz(paste0(getwd(),"/out/data_csv.zip"), "Results.csv"),
results sep=";", encoding = "UTF-8")
Datenabruf und Konvertierung der Daten mit LogFSM
Mit dem Aufruf der Funktion TransformToUniversalLogFormat
aus dem Paket LogFSM
werden die Daten heruntergeladen und in das spezifizierte Verzeichnis infolders
abgelegt, wenn ein API-Key (key
) und eine API-Url (web
) übergeben werden.
SECRET_KEY
und API_URL
Der Wert für SECRET_KEY
muss dem Eintrag entsprechen, der bei der Konfiguration des Docker-Images in der appsettings.json
als ExternalExportKey
definiert wurde, siehe Abschnitt Online-Version (Docker).
Der Wert für die API_URL
bildet sich nach folgendem Schema: https://{U}/{S}/api/session/
{U}
ist die URL des IRTlib Players{S}
ist der Bezeichner der Studie
Die Funktion TransformToUniversalLogFormat
aus dem Paket LogFSM
(oder analog dem im Folgenden beschriebenen Kommandozeilenwerkzeug) können auch verwendet werden, um bereits lokal vorhandene Rohdatenarchive auszulesen.
Datenabruf über die Kommandozeile
Die für den Datenabruf und die Datenkonvertierung über LogFSM
verwendete Anwendung TransformToUniversalLogFormat
ist als Konsolen-Anwendung aus dem Releases-Abschnitt von https://github.com/kroehne/LogFSM/ verfügbar.
Darüber lassen sich Datenabruf und Datenumwandlung auch ohne R ausführen.
Eine zertifizierte Version von TransformToUniversalLogFormat
für Apple ist im Moment in Entwicklung.
Ergebnisdaten
Wenn die Daten über LogFSM
von einem Online IRTlib Player abgerufen oder Offline eingesammelt wurden, liegen sie am Ende in einem Verzeichnis vor. Je Session (d.h. je Person oder Person x Zeitpunkt) als Rohdaten-Archiv.
Die Funktion TransformToUniversalLogFormat
in LogFSM
oder über die Kommando-Zeile kann auch verwendet werden, um die Rohdatenarchive aus einem Verzeichnis auszulesen und die Ergebnisdaten zu extrahieren:
library(LogFSM)
if (!dir.exists(paste0(getwd(),"/out/")))
dir.create(paste0(getwd(),"/out/"))
::TransformToUniversalLogFormat(inputfolders = paste0(getwd(),"/in/"),
LogFSMinputformat = "irtlibv01a",
zcsvoutput = paste0(getwd(),"/out/data_csv.zip"),
stataoutput = paste0(getwd(),"/out/data_dta.zip"),
spssoutput = paste0(getwd(),"/out/data_sav.zip"),
outputtimestampformatstring="dd.MM.yyyy HH:mm:ss.fff")
<- read.csv(unz(paste0(getwd(),"/out/data_csv.zip"), "Results.csv"),
results sep=";", encoding = "UTF-8")
Log-Daten
Die Konvertierung der Daten mit TransformToUniversalLogFormat
in LogFSM
oder über die Kommando-Zeile wandelt die erhobenen Log-Daten, welche von den CBA ItemBuilder-Tasks bereitgestellt werden, in folgende Formate um:
Flat and Sparse Log-Data Table: Eine große Tabelle (als CSV, Stata, SPSS) mit einer Zeile je Event. Da die eventspezifischen Attribute (d.h. die unterschiedlichen zusätzlichen Informationen, die von einem Event vorhanden sind) sich auf viele Spalten verteilen, die aber jeweils nur je Event-Typ gefüllt sind, ist diese Tabelle zwar flach, aber ggf. auch sehr löchrig.
Universal Log-Format: Alternativ enthalten die von
LogFSM
bzw. dem Kommandozeilen-WerkzeugTransformToUniversalLogFormat
erstellten ZIP-Archive auch einzelne Datensatz-Tabellen je Event-Typ. Die eventspezifischen Attribute in diesen Tabellen sind weniger löchrig (d.h. sie enthalten nur fehlende Werte für optionale Attribute) und können zu einer Flat and Sparse Log-Data Table kombiniert werden, wenn erforderlich.XES (eXtensible Event Stream): Die Log-Daten können auch in dem standardisierten
XML
-Format (https://xes-standard.org/) umgewandelt werden.
Die mit der IRTlib Software erhobenen Zeitstempel sind im UTC-Format (Coordinated Universal Time).
Dateien in den Rohdatenarchiven
Die Rohdatenarchive enthalten folgende Dateien:
Trace.json
: Log-Daten (Traces) wie von der CBA ItemBuilder-Runtime geliefert, zusammen mit dem Kontext aus dem IRTlib Player.
Die Datei enthält folgende Struktur, mit Komma getrennt. Die Datei ist kein gültiges JSON, bis nicht das letzte Komma entfernt und ein
[
vor und ein]
nach dem Inhalt eingefügt wird.
Der Eintrag
Trace
enthält die Log-Daten (Traces) in Päckchen (wie von der CBA ItemBuilder-Runtime geliefert) quotiert (d.h."
wird als\u0022
dargestellt). DieTraceId
ist ein Zähler, welcher die übermittelten Päckchen durchzählt.Timestamp
ist der Zeitstempel der Übermittlung.SessionId
der Benutzername oder die UUID (PersonIdentifier). DerContext
gibt über den Namen des CBA ItemBuilder-Projekts, Task und Scope eine Referenz zum Assessmentinhalt (Element). UnterAssemblies
sind die Informationen zum verwendeten IRTlib Player gespeichert undStudyRevision
verweist auf die Revision einer (veröffentlichten) Studie.
{
"Trace": "(TRACE-JSON)",
"TraceId": 1,
"Timestamp": "2023-12-04T20:53:06.297Z",
"SessionId": "(SESSION-ID OR USERNAME)",
"Context": {
"Item": "(PROJECT NAME)",
"Task": "(TASK NAME)",
"Scope": "(SCOPE)",
"Preview": ""
},
"Assemblies": [
{
"Name": "TestApp.Player.Desktop",
"Version": "(APPLICATION VERSION)",
"GitHash": "(APPLICATION BUILD HASH)"
}
],
"StudyRevision": "(STUDY REVISION)"
},
Snapshot.json
: Snapshot-Daten wie von der CBA ItemBuilder-Runtime geliefert, zusammen mit dem Kontext aus dem IRTlib Player.
Die Datei enthält folgende Struktur, mit Komma getrennt. Die Datei ist kein gültiges JSON, bis nicht das letzte Komma entfernt und ein
[
vor und ein]
nach dem Inhalt eingefügt wird.
Der Eintrag
Snapshot
enthält die Snapshot-Informationen (wie von der CBA ItemBuilder-Runtime geliefert) quotiert (d.h."
wird als\u0022
dargestellt). DerContextFlag
gibt an, wie der CBA ItemBuilder-Task verlassen wurde (NextTask, PreviousTask oder Cancel).Timestamp
ist der Zeitstempel der Übermittlung.SessionId
der Benutzername oder die UUID (PersonIdentifier). DerContext
gibt über Name des CBA ItemBuilder-Projekts, Task und Scope eine Referenz zum Assessmentinhalt (Element). UnterAssemblies
sind die Informationen zum verwendeten IRTlib Player gespeichert undStudyRevision
verweist auf die Revision einer (veröffentlichten) Studie.
{
"Snapshot": "(SNAPSHOT-JSON)",
"ContextFlag": "NextTask",
"ContextScope": 0,
"Timestamp": "2023-12-04T20:53:06.497Z",
"SessionId": "(SESSION-ID OR USERNAME)",
"Context": {
"Item": "(PROJECT NAME)",
"Task": "(TASK NAME)",
"Scope": "(SCOPE)",
"Preview": ""
},
"Assemblies": null,
"StudyRevision": null
},
ItemScore.json
: Scoring-Information (wie von CBA ItemBuilder-Runtime geliefert).
Die Datei enthält folgende Struktur, mit Komma getrennt. Die Datei ist kein gültiges JSON, bis nicht das letzte Komma entfernt und ein
[
vor und ein]
nach dem Inhalt eingefügt wird.
Der Eintrag
ItemScore
enthält den ItemScore (wie von der CBA ItemBuilder-Runtime geliefert) quotiert (d.h."
wird als\u0022
dargestellt).DerContextFlag
gibt an, wie der CBA ItemBuilder-Task verlassen wurde (NextTask, PreviousTask oder Cancel).Timestamp
ist der Zeitstempel der Übermittlung.SessionId
der Benutzername oder die UUID (PersonIdentifier). DerContext
gibt über Name des CBA ItemBuilder-Projekts, Task und Scope eine Referenz zum Assessmentinhalt (Element). UnterAssemblies
sind die Informationen zum verwendeten IRTlib Player gespeichert undStudyRevision
verweist auf die Revision einer (veröffentlichten) Studie.
{
"ItemScore": "(SCORING-JSON)",
"ContextFlag": "NextTask",
"ContextScope": 0,
"Timestamp": "2023-12-04T20:53:06.474Z",
"SessionId": "(SESSION-ID OR USERNAME)",
"Context": {
"Item": "(PROJECT NAME)",
"Task": "(TASK NAME)",
"Scope": "(SCOPE)",
"Preview": ""
},
"Assemblies": [
{
"Name": "TestApp.Player.Desktop",
"Version": "(APPLICATION VERSION)",
"GitHash": "(APPLICATION BUILD HASH)"
}
],
"StudyRevision": "(STUDY REVISION)"
},
Session.json
: Die Datei enthält Daten des IRTlib Players, welche die Ausführung der Session beschreiben.Log.json
: Log-Events der IRTlib Player (enthält u.A. Log-Informationen zur Verarbeitung des Blockly-Routings).browser.log
: Ausgabe der Konsole, die während der Bearbeitung der Aufgaben im Browser gesammelt wurden (unstrukturierter Text, für Entwickler).server.log
: Log-Ausgaben des Servers des IRTlib Players (unstruktruierter Text, für Entwickler)Keyboard.json
: Tastatureingaben und Zeitstempel.Monitoring.json
: Kopie der Monitoring-Datei, welche erstellt wurde.