public override string HandleDataTable(UXFDataTable table, string experiment, string ppid, int sessionNum, string dataName, UXFDataType dataType, int optionalTrialNum = 0) { string ext = Path.GetExtension(dataName); dataName = Path.GetFileNameWithoutExtension(dataName); if (dataType.GetDataLevel() == UXFDataLevel.PerTrial) { dataName = string.Format("{0}_T{1:000}", dataName, optionalTrialNum); } string[] lines = table.GetCSVLines(); string directory = GetSessionPath(experiment, ppid, sessionNum); if (sortDataIntoFolders && dataType != UXFDataType.TrialResults) { directory = Path.Combine(directory, dataType.ToLower()); } Directory.CreateDirectory(directory); string name = string.IsNullOrEmpty(ext) ? string.Format("{0}.csv", dataName) : string.Format("{0}{1}", dataName, ext); string savePath = Path.Combine(directory, name); if (verboseDebug) { Utilities.UXFDebugLogFormat("Queuing save of file: {0}", savePath); } ManageInWorker(() => { File.WriteAllLines(savePath, lines); }); return(GetRelativePath(storagePath, savePath));; }
public override string HandleDataTable(UXFDataTable table, string experiment, string ppid, int sessionNum, string dataName, UXFDataType dataType, int optionalTrialNum = 0) { // get data as text string[] lines = table.GetCSVLines(); string text = string.Join("\n", lines); string ext = Path.GetExtension(dataName); dataName = Path.GetFileNameWithoutExtension(dataName); if (dataType.GetDataLevel() == UXFDataLevel.PerTrial) { dataName = string.Format("{0}_T{1:000}", dataName, optionalTrialNum); } string directory = GetSessionPathRelative(experiment, ppid, sessionNum); if (dataType != UXFDataType.TrialResults) { directory = Path.Combine(directory, dataType.ToLower()); } string name = string.IsNullOrEmpty(ext) ? string.Format("{0}.csv", dataName) : string.Format("{0}{1}", dataName, ext); string savePath = Path.Combine(directory, name); savePath = savePath.Replace('\\', '/'); // here we send our data request AuthenticatedRequest(savePath, text); // return a string representing the location of the data. Will be stored in the trial_results output. return(savePath); }
public override string HandleDataTable(UXFDataTable table, string experiment, string ppid, int sessionNum, string dataName, UXFDataType dataType, int optionalTrialNum = 0) { if (dataType.GetDataLevel() == UXFDataLevel.PerTrial) { dataName = string.Format("{0}_T{1:000}", dataName, optionalTrialNum); } string[] lines = table.GetCSVLines(); string directory = GetSessionPath(experiment, ppid, sessionNum); if (sortDataIntoFolders && dataType != UXFDataType.TrialResults) { directory = Path.Combine(directory, dataType.ToLower()); } Directory.CreateDirectory(directory); string savePath = Path.Combine(directory, string.Format("{0}.csv", dataName)); if (verboseDebug) { Debug.LogFormat("Queuing save of file: {0}", savePath); } ManageInWorker(() => { File.WriteAllLines(savePath, lines); }); return(savePath); }
/// <summary> /// Ends the experiment session. /// </summary> public void End() { if (hasInitialised) { isEnding = true; if (InTrial) { try { CurrentTrial.End(); } catch (Exception e) { Debug.LogException(e); } } SaveResults(); try { preSessionEnd.Invoke(this); } catch (Exception e) { Debug.LogException(e); } if (storeSessionSettings) { // copy Settings to session folder SaveJSONSerializableObject(new Dictionary <string, object>(settings.baseDict), "settings", dataType: UXFDataType.Settings); } if (storeParticipantDetails) { // copy participant details to session folder // we convert to a DataTable because we know the dictionary will be "flat" (one value per key) UXFDataTable ppDetailsTable = new UXFDataTable(participantDetails.Keys.ToArray()); var row = new UXFDataRow(); foreach (var kvp in participantDetails) { row.Add((kvp.Key, kvp.Value)); } ppDetailsTable.AddCompleteRow(row); var ppDetailsLines = ppDetailsTable.GetCSVLines(); SaveDataTable(ppDetailsTable, "participant_details", dataType: UXFDataType.ParticipantDetails); } // end DataHandlers - forces completion of tasks foreach (var dataHandler in ActiveDataHandlers) { try { dataHandler.CleanUp(); } catch (Exception e) { Debug.LogException(e); } } try { onSessionEnd.Invoke(this); } catch (Exception e) { Debug.LogException(e); } currentTrialNum = 0; currentBlockNum = 0; blocks = new List <Block>(); _hasInitialised = false; Utilities.UXFDebugLog("Ended session."); isEnding = false; } }
/// <summary> /// Initialises the session logger, creating the internal data structures, and attaching its logging method to handle Debug.Log messages /// </summary> public void Initialise() { table = new UXFDataTable("timestamp", "log_type", "message"); if (logDebugLogCalls) { Application.logMessageReceived += HandleLog; } session.preSessionEnd.AddListener(Finalise); // finalise logger when cleaning up the session }
/// <summary> /// Handles a UXF Data Table. Should not normally be called by the user. Instead, call session.SaveDataTable() or trial.SaveDataTable(). /// </summary> /// <param name="table"></param> /// <param name="experiment"></param> /// <param name="ppid"></param> /// <param name="sessionNum"></param> /// <param name="dataName"></param> /// <param name="dataType"></param> /// <param name="optionalTrialNum"></param> public override string HandleDataTable(UXFDataTable table, string experiment, string ppid, int sessionNum, string dataName, UXFDataType dataType, int optionalTrialNum) { if (!CheckCurrentTargetOK()) { return("not supported in editor"); } if (dataType == UXFDataType.TrialResults) { // special case, one item per trial, but multiple items // so we need BatchWriteItem string primaryKeyValue = GetFormattedPrimaryKeyValue(ppid, sessionNum, dataName); string tableName = GetTableName(experiment, dataType); if (!table.Headers.Contains("trial_num")) { Debug.LogError("Data supplied is supposed to be per-trial but does not contain 'trial_num' column!"); return("error"); } var dataList = table.GetAsListOfDict() .Select(item => { item[primaryKey] = primaryKeyValue; return(item); }) .Cast <object>() .ToList(); if (dataList.Count <= 25) { string req = MiniJSON.Json.Serialize(dataList); DDB_BatchWriteItem(tableName, req, gameObject.name); } else { // BatchWriteItem accepts 25 items at most while (dataList.Any()) { var dataListChunk = dataList.Take(25).ToList(); dataList = dataList.Skip(25).ToList(); string req = MiniJSON.Json.Serialize(dataListChunk); DDB_BatchWriteItem(tableName, req, gameObject.name); } } return(string.Format("dynamodb:{0}:{1}", tableName, primaryKeyValue)); } else { Dictionary <string, object> dataDict = table .GetAsDictOfList() .ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value); return(HandleJSONSerializableObject(dataDict, experiment, ppid, sessionNum, dataName, dataType, optionalTrialNum)); } }
/// <summary> /// Saves a DataTable to the storage locations(s). /// </summary> /// <param name="table">The data to be saved.</param> /// <param name="dataName">Name to be used in saving.</param> /// <param name="dataType"></param> public void SaveDataTable(UXFDataTable table, string dataName, UXFDataType dataType = UXFDataType.OtherSessionData) { if (!CheckDataTypeIsValid(dataName, dataType)) { dataType = UXFDataType.OtherSessionData; } foreach (var dataHandler in ActiveDataHandlers) { string location = dataHandler.HandleDataTable(table, experimentName, ppid, number, dataName, dataType); } }
/// <summary> /// Initialises a Session /// </summary> /// <param name="experimentName">A name for the experiment</param> /// <param name="participantId">A unique ID associated with a participant</param> /// <param name="baseFolder">Location where data should be stored</param> /// <param name="sessionNumber">A number for the session (optional: default 1)</param> /// <param name="participantDetails">Dictionary of information about the participant to be used within the experiment (optional: default null)</param> /// <param name="settings">A Settings instance (optional: default empty settings)</param> public void Begin(string experimentName, string participantId, int sessionNumber = 1, Dictionary <string, object> participantDetails = null, Settings settings = null) { this.experimentName = experimentName; ppid = participantId; number = sessionNumber; if (participantDetails == null) { participantDetails = new Dictionary <string, object>(); } this.participantDetails = participantDetails; if (settings == null) { settings = Settings.empty; } this.settings = settings; // Initialise DataHandlers foreach (var dataHandler in ActiveDataHandlers) { dataHandler.Initialise(this); dataHandler.SetUp(); } _hasInitialised = true; // raise the session events onSessionBegin.Invoke(this); if (storeSessionSettings) { // copy Settings to session folder SaveJSONSerializableObject(new Dictionary <string, object>(settings.baseDict), "settings", dataType: UXFDataType.Settings); } if (storeParticipantDetails) { // copy participant details to session folder // we convert to a DataTable because we know the dictionary will be "flat" (one value per key) UXFDataTable ppDetailsTable = new UXFDataTable(participantDetails.Keys.ToArray()); var row = new UXFDataRow(); foreach (var kvp in participantDetails) { row.Add((kvp.Key, kvp.Value)); } ppDetailsTable.AddCompleteRow(row); var ppDetailsLines = ppDetailsTable.GetCSVLines(); SaveDataTable(ppDetailsTable, "participant_details", dataType: UXFDataType.ParticipantDetails); } }
/// <summary> /// Saves a DataTable to the storage locations(s) for this trial. A column will be added in the trial_results CSV listing the location(s) of these data. /// </summary> /// <param name="table">The data to be saved.</param> /// <param name="dataName">Name to be used in saving. It will be appended with the trial number.</param> /// <param name="dataType"></param> public void SaveDataTable(UXFDataTable table, string dataName, UXFDataType dataType = UXFDataType.OtherTrialData) { if (!CheckDataTypeIsValid(dataName, dataType)) { dataType = UXFDataType.OtherTrialData; } int i = 0; foreach (var dataHandler in session.ActiveDataHandlers) { string location = dataHandler.HandleDataTable(table, session.experimentName, session.ppid, session.number, dataName, dataType, number); result[string.Format("{0}_location_{1}", dataName, i++)] = location.Replace("\\", "/"); } }
/// <summary> /// Handles a UXF Data Table. Should not normally be called by the user. Instead, call session.SaveDataTable() or trial.SaveDataTable(). /// </summary> /// <param name="table"></param> /// <param name="experiment"></param> /// <param name="ppid"></param> /// <param name="sessionNum"></param> /// <param name="dataName"></param> /// <param name="dataType"></param> /// <param name="optionalTrialNum"></param> public override string HandleDataTable(UXFDataTable table, string experiment, string ppid, int sessionNum, string dataName, UXFDataType dataType, int optionalTrialNum) { if (!CheckCurrentTargetOK()) { return("not supported in editor"); } if (dataType == UXFDataType.TrialResults) { // special case, one item per trial, but multiple items // so we need BatchWriteItem string primaryKeyValue = GetFormattedPrimaryKeyValue(ppid, sessionNum, dataName); string tableName = GetTableName(experiment, dataType); if (!table.Headers.Contains("trial_num")) { Utilities.UXFDebugLogError("Data supplied is supposed to be per-trial but does not contain 'trial_num' column!"); return("error"); } var dataList = table.GetAsListOfDict() .Select(item => { item[primaryKey] = primaryKeyValue; return(item); }) .Cast <object>(); // split the request into batches of 25 because of limit in DynamoDB BatchWriteItem var batches = dataList.Batch(25); foreach (var batch in batches) { string req = MiniJSON.Json.Serialize(batch.ToList()); DDB_BatchWriteItem(tableName, req, gameObject.name); } return(string.Format("dynamodb:{0}:{1}", tableName, primaryKeyValue)); } else { Dictionary <string, object> dataDict = table .GetAsDictOfList() .ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value); return(HandleJSONSerializableObject(dataDict, experiment, ppid, sessionNum, dataName, dataType, optionalTrialNum)); } }
void SaveResults() { // generate list of all headers possible // hashset keeps unique set of keys HashSet <string> resultsHeaders = new HashSet <string>(); foreach (Trial t in Trials) { if (t.result != null) { foreach (string key in t.result.Keys) { resultsHeaders.Add(key); } } } UXFDataTable table = new UXFDataTable(Trials.Count(), resultsHeaders.ToArray()); foreach (Trial t in Trials) { if (t.result != null) { UXFDataRow row = new UXFDataRow(); foreach (string h in resultsHeaders) { if (t.result.ContainsKey(h) && t.result[h] != null) { row.Add((h, t.result[h])); } else { row.Add((h, string.Empty)); } } table.AddCompleteRow(row); } } SaveDataTable(table, "trial_results", dataType: UXFDataType.TrialResults); }
/// <summary> /// Begins recording. /// </summary> public void StartRecording() { data = new UXFDataTable(header); recording = true; }
private void OnEnable() { _target = gameObject.GetComponent <CalibrationAssessment>(); SetupDescriptorAndHeader(); data = new UXFDataTable(header); }
public abstract string HandleDataTable(UXFDataTable table, string experiment, string ppid, int sessionNum, string dataName, UXFDataType dataType, int optionalTrialNumber = 0);