/// <summary> /// Add a complete row to the table /// </summary> /// <param name="newRow"></param> public void AddCompleteRow(UXFDataRow newRow) { bool sameKeys = (dict .Keys .All( newRow .Select(item => item.columnName) .Contains )) && (newRow.Count == dict.Keys.Count); if (!sameKeys) { throw new InvalidOperationException( string.Format( "The row does not contain values for the same columns as the columns in the table!\nTable: {0}\nRow: {1}", string.Join(", ", Headers), string.Join(", ", newRow.Headers) ) ); } foreach (var item in newRow) { dict[item.columnName].Add(item.value); } }
/// <summary> /// Records a new row of data at current time. /// </summary> public void RecordRow() { UXFDataRow newRow = GetCurrentValues(); newRow.Add(("time", Time.time)); data.AddCompleteRow(newRow); }
/// <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> /// Returns current position and rotation values /// </summary> /// <returns></returns> protected override UXFDataRow GetCurrentValues() { var dataRow = new UXFDataRow(); const string format = "0.####"; // return position, rotation (x, y, z) as an array var position = _target.CurrentTargetTransform.position; var localPosition = _target.CurrentTargetTransform.localPosition; var values = new(string, object)[]
/// <summary> /// Manually log a message to the log file. /// </summary> /// <param name="logType">The type of the log. This can be any string you choose.</param> /// <param name="message">The content you wish to log, expressed as a string.</param> public void WriteLog(string logType, string value) { var row = new UXFDataRow(); row.Add(("timestamp", Time.time.ToString())); row.Add(("log_type", logType)); row.Add(("message", value.Replace(",", string.Empty))); table.AddCompleteRow(row); }
void HandleLog(string logString, string stackTrace, LogType type) { var row = new UXFDataRow(); row.Add(("timestamp", Time.time.ToString())); row.Add(("log_type", type.ToString())); row.Add(("message", logString.Replace(",", string.Empty))); table.AddCompleteRow(row); }
/// <summary> /// Manually log a message to the log file. /// </summary> /// <param name="text">The content you wish to log, expressed as a string.</param> /// <param name="logType">The type of the log. This can be any string you choose. Default is \"user\"</param> public void Log(string text, string logType = "user") { var row = new UXFDataRow(); row.Add(("timestamp", Time.time.ToString())); row.Add(("log_type", logType)); row.Add(("message", text.Replace(",", string.Empty))); table.AddCompleteRow(row); }
/// <summary> /// Records a new row of data at current time. /// </summary> public void RecordRow() { if (!recording) { throw new System.InvalidOperationException("Tracker measurements cannot be taken when not in a trial!"); } UXFDataRow newRow = GetCurrentValues(); newRow.Add(("time", Time.time)); data.AddCompleteRow(newRow); }
/// <summary> /// Manually log a message to the log file. /// </summary> /// <param name="text">The content you wish to log, expressed as a string.</param> /// <param name="logType">The type of the log. This can be any string you choose. Default is \"user\"</param> public void Log(string text, string logType = "user") { var row = new UXFDataRow(); row.Add(("unity_timestamp", Time.time.ToString())); row.Add(("host_timestamp", UXF.ApplicationHandler.CurrentHighResolutionTime)); row.Add(("log_type", logType)); row.Add(("message", text.Replace(",", string.Empty))); row.Add(("stacktrace", "NA")); table.AddCompleteRow(row); }
void HandleLog(string logString, string stackTrace, LogType type) { var row = new UXFDataRow(); row.Add(("unity_timestamp", Time.time.ToString())); row.Add(("host_timestamp", UXF.ApplicationHandler.CurrentHighResolutionTime)); row.Add(("log_type", type.ToString())); row.Add(("message", logString.Replace(",", string.Empty))); row.Add(("stacktrace", stackTrace.Replace(",", string.Empty).Replace("\n", ". ").Replace("\r", ". "))); table.AddCompleteRow(row); }
/// <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> /// Records a new row of data at current time. /// </summary> public void RecordRow() { if (!recording) { throw new System.InvalidOperationException("Tracker measurements cannot be taken when not in a trial!"); } UXFDataRow newRow = GetCurrentValues(); newRow.Add(("unity_timestamp", UnityEngine.Time.time)); newRow.Add(("host_timestamp", UXF.ApplicationHandler.CurrentHighResolutionTime)); data.AddCompleteRow(newRow); }
public void DataTableCSV() { Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); var dt = new UXFDataTable("null", "float", "comma", "period"); var row = new UXFDataRow(); row.Add(("null", null)); row.Add(("float", 3.14f)); row.Add(("comma", "i have, commas")); row.Add(("period", "i have, periods")); dt.AddCompleteRow(row); string expected = string.Join("\n", new string[] { "null,float,comma,period", "null,3.14,i have_ commas,i have_ periods" }); string csv = string.Join("\n", dt.GetCSVLines()); Assert.AreEqual(expected, csv); }
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); }