Skip to content

Commit fb3d0ba

Browse files
author
Jack Brookes
committed
Checkbox for ad-hoc results adding & tests
1 parent 5d7e55f commit fb3d0ba

File tree

14 files changed

+160
-68
lines changed

14 files changed

+160
-68
lines changed

Assets/UXF/Scripts/Etc/Trial.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public class Trial
5151
/// <summary>
5252
/// Dictionary of results in a order.
5353
/// </summary>
54-
public OrderedResultDict result;
54+
public ResultsDictionary result;
5555

5656
/// <summary>
5757
/// Manually create a trial. When doing this you need to add this trial to a block with block.trials.Add(trial)
@@ -82,9 +82,7 @@ public void Begin()
8282

8383
status = TrialStatus.InProgress;
8484
startTime = Time.time;
85-
result = new OrderedResultDict();
86-
foreach (string h in session.Headers)
87-
result.Add(h, string.Empty);
85+
result = new ResultsDictionary(session.Headers, session.adHocHeaderAdd);
8886

8987
result["directory"] = Extensions.CombinePaths(session.experimentName, session.ppid, session.FolderName).Replace('\\', '/');
9088
result["experiment"] = session.experimentName;

Assets/UXF/Scripts/FileIOManager.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -205,23 +205,34 @@ public void WriteJson(object serializableObject, WriteFileInfo writeFileInfo)
205205
/// <summary>
206206
/// Writes trial data (List of OrderedResultsDict) to file at fpath
207207
/// </summary>
208-
/// <param name="dataDict"></param>
209-
/// <param name="headers"></param>
208+
/// <param name="dictList"></param>
210209
/// <param name="fpath"></param>
211-
public void WriteTrials(List<OrderedResultDict> dataDict, string[] headers, WriteFileInfo writeFileInfo)
210+
public void WriteTrials(List<ResultsDictionary> dictList, WriteFileInfo writeFileInfo)
212211
{
213-
string[] csvRows = new string[dataDict.Count + 1];
214-
csvRows[0] = string.Join(",", headers.ToArray());
215-
object[] row = new object[headers.Length];
212+
// generate list of all headers possible
213+
// hashset keeps unique set of keys
214+
HashSet<string> headers = new HashSet<string>();
215+
foreach (ResultsDictionary dict in dictList)
216+
foreach (string key in dict.Keys)
217+
headers.Add(key);
218+
219+
// final output: array of rows (comma-separated strings)
220+
string[] csvRows = new string[dictList.Count + 1];
216221

217-
for (int i = 1; i <= dataDict.Count; i++)
222+
// first row: headers
223+
csvRows[0] = string.Join(",", headers.ToArray());
224+
225+
for (int i = 0; i < dictList.Count; i++)
218226
{
219-
OrderedResultDict dict = dataDict[i - 1];
220-
if (dict != null)
221-
{
222-
dict.Values.CopyTo(row, 0);
223-
csvRows[i] = string.Join(",", row.Select(v => System.Convert.ToString(v)).ToArray());
224-
}
227+
ResultsDictionary dict = dictList[i];
228+
229+
// add all observations to the row, in correct order.
230+
// check if null, if so assign to empty string (?? operator)
231+
var row = headers
232+
.Select(header => (dict[header] ?? string.Empty).ToString());
233+
234+
// join to string & store in output
235+
csvRows[i + 1] = string.Join(",", row.ToArray());
225236
}
226237

227238
File.WriteAllLines(writeFileInfo.FullPath, csvRows);

Assets/UXF/Scripts/Session.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ public class Session : MonoBehaviour
3636
/// </summary>
3737
[Tooltip("Enable to automatically end the session when the final trial has ended.")]
3838
public bool endAfterLastTrial = false;
39+
40+
/// <summary>
41+
/// If enabled, results that are not listed in Custom Headers can be added at any time. If disabled, adding results that are not listed in Custom Headers will throw an error.
42+
/// </summary>
43+
[Tooltip("If enabled, results that are not listed in Custom Headers can be added at any time. If disabled, adding results that are not listed in Custom Headers will throw an error.")]
44+
public bool adHocHeaderAdd = false;
45+
3946

4047
/// <summary>
4148
/// List of blocks for this experiment
@@ -719,9 +726,8 @@ public void End()
719726

720727
void SaveResults()
721728
{
722-
List<OrderedResultDict> results = Trials.Select(t => t.result).ToList();
729+
List<ResultsDictionary> results = Trials.Select(t => t.result).ToList();
723730
string fileName = "trial_results.csv";
724-
725731
WriteFileInfo fileInfo = new WriteFileInfo(
726732
WriteFileType.Trials,
727733
BasePath,
@@ -731,7 +737,7 @@ void SaveResults()
731737
fileName
732738
);
733739

734-
fileIOManager.ManageInWorker(() => fileIOManager.WriteTrials(results, Headers.ToArray(), fileInfo));
740+
fileIOManager.ManageInWorker(() => fileIOManager.WriteTrials(results, fileInfo));
735741
}
736742

737743

Assets/UXF/Scripts/Tests/Editor/TestTrials.cs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ public class TestTrials
1818
FileIOManager fileIOManager;
1919
SessionLogger sessionLogger;
2020

21-
[SetUp]
22-
public void SetUp()
21+
void Start(bool adHoc)
2322
{
2423
gameObject = new GameObject();
2524
fileIOManager = gameObject.AddComponent<FileIOManager>();
@@ -30,6 +29,8 @@ public void SetUp()
3029
fileIOManager
3130
);
3231

32+
session.adHocHeaderAdd = adHoc;
33+
3334
sessionLogger.AttachReferences(
3435
fileIOManager,
3536
session
@@ -41,7 +42,7 @@ public void SetUp()
4142
fileIOManager.Begin();
4243

4344
string experimentName = "unit_test";
44-
string ppid = "test_trials";
45+
string ppid = "test_trials" + (adHoc ? "_adhoc" : "");
4546
session.Begin(experimentName, ppid, "example_output");
4647
session.customHeaders.Add("observation");
4748
session.customHeaders.Add("null_observation");
@@ -51,8 +52,7 @@ public void SetUp()
5152
session.CreateBlock(3);
5253
}
5354

54-
[TearDown]
55-
public void TearDown()
55+
void Finish()
5656
{
5757
session.End();
5858
fileIOManager.End();
@@ -62,6 +62,7 @@ public void TearDown()
6262
[Test]
6363
public void RunTrials()
6464
{
65+
Start(false);
6566
int i = 0;
6667
foreach (var trial in session.Trials)
6768
{
@@ -84,6 +85,41 @@ public void RunTrials()
8485
{
8586
Assert.AreEqual(trial.result["observation"], ++i);
8687
}
88+
Finish();
89+
90+
// read the file to check headers
91+
string firstLine = File.ReadAllLines(Path.Combine(session.FullPath, "trial_results.csv"))[0];
92+
Assert.AreEqual("directory,experiment,ppid,session_num,trial_num,block_num,trial_num_in_block,start_time,end_time,observation,null_observation", firstLine);
93+
}
94+
95+
[Test]
96+
public void RunTrialsAdHocResultsAdd()
97+
{
98+
Start(true);
99+
int i = 0;
100+
foreach (var trial in session.Trials)
101+
{
102+
trial.Begin();
103+
trial.result["observation"] = ++i;
104+
trial.result["null_observation"] = null;
105+
trial.result["not_customheader_observation"] = "something";
106+
107+
Assert.AreSame(trial, session.CurrentTrial);
108+
Assert.AreEqual(trial.number, session.currentTrialNum);
109+
110+
trial.End();
111+
}
112+
113+
i = 0;
114+
foreach (var trial in session.Trials)
115+
{
116+
Assert.AreEqual(trial.result["observation"], ++i);
117+
}
118+
Finish();
119+
120+
// read the file to check headers
121+
string firstLine = File.ReadAllLines(Path.Combine(session.FullPath, "trial_results.csv"))[0];
122+
Assert.AreEqual("directory,experiment,ppid,session_num,trial_num,block_num,trial_num_in_block,start_time,end_time,observation,null_observation,not_customheader_observation", firstLine);
87123
}
88124

89125
}

Assets/UXF/Scripts/UI/OrderedResultDict.cs

Lines changed: 0 additions & 32 deletions
This file was deleted.

Assets/UXF/Scripts/UI/ResultsDict.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Collections.Specialized;
6+
7+
namespace UXF
8+
{
9+
public class ResultsDictionary
10+
{
11+
private Dictionary<string, object> baseDict;
12+
private bool allowAdHocAdding;
13+
14+
/// <summary>
15+
/// Dictionary of results for a trial.
16+
/// </summary>
17+
/// <param name="initialKeys">Initial keys (e.g. headers) to add to dictionary</param>
18+
/// <param name="allowAdHocAdding">Should extra keys be allowed to be added ad-hoc?</param>
19+
public ResultsDictionary(IEnumerable<string> initialKeys, bool allowAdHocAdding)
20+
{
21+
baseDict = new Dictionary<string, object>();
22+
this.allowAdHocAdding = allowAdHocAdding;
23+
foreach (var key in initialKeys)
24+
{
25+
baseDict.Add(key, string.Empty);
26+
}
27+
}
28+
29+
/// <summary>
30+
/// Access or set an observation
31+
/// </summary>
32+
/// <param name="key">Name (header) of the observation</param>
33+
/// <returns></returns>
34+
public object this[string key]
35+
{
36+
get { return baseDict[key]; }
37+
set {
38+
if (allowAdHocAdding || baseDict.ContainsKey(key))
39+
{
40+
baseDict[key] = value;
41+
}
42+
else
43+
{
44+
throw new KeyNotFoundException(string.Format("Custom header \"{0}\" does not exist!", key));
45+
}
46+
}
47+
}
48+
49+
public Dictionary<string, object>.KeyCollection Keys
50+
{
51+
get
52+
{
53+
return baseDict.Keys;
54+
}
55+
}
56+
57+
}
58+
59+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
timestamp,log_type,message
2-
1.979085,Log,Joining FileIOManagerThread
2+
1.353333,Warning,Warning: Session already exists! Continuing will overwrite
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
3-
}
2+
3+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
3-
}
2+
3+
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
experiment,ppid,session_num,trial_num,block_num,trial_num_in_block,start_time,end_time,observation,null_observation
2-
unit_test,test_trials,1,1,1,1,1.979085,1.979085,1,
3-
unit_test,test_trials,1,2,1,2,1.979085,1.979085,2,
4-
unit_test,test_trials,1,3,2,1,1.979085,1.979085,3,
5-
unit_test,test_trials,1,4,2,2,1.979085,1.979085,4,
6-
unit_test,test_trials,1,5,2,3,1.979085,1.979085,5,
1+
directory,experiment,ppid,session_num,trial_num,block_num,trial_num_in_block,start_time,end_time,observation,null_observation
2+
unit_test/test_trials/S001,unit_test,test_trials,1,1,1,1,1.353333,1.353333,1,
3+
unit_test/test_trials/S001,unit_test,test_trials,1,2,1,2,1.353333,1.353333,2,
4+
unit_test/test_trials/S001,unit_test,test_trials,1,3,2,1,1.353333,1.353333,3,
5+
unit_test/test_trials/S001,unit_test,test_trials,1,4,2,2,1.353333,1.353333,4,
6+
unit_test/test_trials/S001,unit_test,test_trials,1,5,2,3,1.353333,1.353333,5,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
timestamp,log_type,message
2+
1.010086,Warning,Warning: Session already exists! Continuing will overwrite
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
directory,experiment,ppid,session_num,trial_num,block_num,trial_num_in_block,start_time,end_time,observation,null_observation,not_customheader_observation
2+
unit_test/test_trials_adhoc/S001,unit_test,test_trials_adhoc,1,1,1,1,1.010086,1.010086,1,,something
3+
unit_test/test_trials_adhoc/S001,unit_test,test_trials_adhoc,1,2,1,2,1.010086,1.010086,2,,something
4+
unit_test/test_trials_adhoc/S001,unit_test,test_trials_adhoc,1,3,2,1,1.010086,1.010086,3,,something
5+
unit_test/test_trials_adhoc/S001,unit_test,test_trials_adhoc,1,4,2,2,1.010086,1.010086,4,,something
6+
unit_test/test_trials_adhoc/S001,unit_test,test_trials_adhoc,1,5,2,3,1.010086,1.010086,5,,something

0 commit comments

Comments
 (0)