IEnumerator CalculateSpearman() { while (!_shouldStop) { _spearmanIsRunning = true; TimeSpan calcStart = new TimeSpan(); calcStart = PupilGazeTracker.Instance._globalTime; List <MovingObject> _tempObjects = new List <MovingObject>(); _cloningInProgress = true; foreach (MovingObject mo in sceneObjects) { _tempObjects.Add((MovingObject)mo.Clone()); //work on a copy to (hopefully) improve performance } MovingObject _tempGaze = (MovingObject)gazeTrajectory.Clone(); _cloningInProgress = false; List <double> _tempXPgaze = new List <double>(_tempGaze.getXPoints()); List <double> _tempYPgaze = new List <double>(_tempGaze.getYPoints()); // write gaze points in logfile //foreach (double dx in _tempXPgaze) trajectoryWriter.WriteLine("gazex;" + calcStart.TotalSeconds + dx); //foreach (double dy in _tempYPgaze) trajectoryWriter.WriteLine("gazey;" + calcStart.TotalSeconds + dy); List <float> results = new List <float>(); foreach (MovingObject mo in _tempObjects) { // temporary list for not having to generate a new one at every loop List <double> _tempXPObj = new List <double>(mo.getXPoints()); List <double> _tempYPObj = new List <double>(mo.getYPoints()); // write object coordinates to logfile //foreach (double dx in _tempXPObj) trajectoryWriter.WriteLine(mo.name + ";" + calcStart.TotalSeconds + dx); //foreach (double dy in _tempXPObj) trajectoryWriter.WriteLine(mo.name + ";" + calcStart.TotalSeconds + dy); // surround calculation with try/catch block or else coroutine will end if something is divided by zero try { double coeffX = Spearman.calculateSpearman(_tempXPgaze, _tempXPObj); double coeffY = Spearman.calculateSpearman(_tempYPgaze, _tempYPObj); correlationWriter.WriteLine(mo.name + ";" + calcStart.TotalSeconds + ";" + coeffX + ";" + coeffY + ";" + w + ";" + corrWindow + ";" + corrFrequency + ";" + Coefficient + ";" + Gaze); // add result to the MovingObject in the original list results.Add((float)sceneObjects.Find(x => x.Equals(mo)).addSample(calcStart, (coeffX + coeffY) / 2, corrWindow)); } catch (Exception e) { Debug.LogError(e.StackTrace); } } //activate only one item at a time for (int i = 0; i < results.Count; i++) { // activate the object with the highest correlation value only if it's above threshold if (results[i].CompareTo(results.Max()) == 0 && results[i] > threshold / 2) { _tempObjects[i].activate(true); //doesn't matter if original or clone list is used as both refer to the same GameObject } else { _tempObjects[i].activate(false); } } calcDur = PupilGazeTracker.Instance._globalTime - calcStart; yield return(new WaitForSeconds(corrFrequency - (float)calcDur.TotalSeconds)); // calculation should take place every x seconds } }