public Map<Integer, SingleRunScore> scoreSubject(Experiment goldStandard, TobiiData subjectData, Map<Integer, List<Double>> recordMap, double lookThreshold) {

		Map<Integer, SingleRunScore> scoreMap = new HashMap<Integer, SingleRunScore>();
		for(Integer trialID : goldStandard.getTrials().keySet()) {

			Trial trial = goldStandard.getTrials().get(trialID);
			
			// Old version: exactly as many Tobii trials as there are Track-It trials
			//Trajectory<TobiiFrame> subjectTrajectory = subjectData.getTrajectories().get(trialID);

			// Newer version: must infer Tobii trials by Spacebar press + closest timestamp match

			Trajectory<TobiiFrame> subjectTrajectory = subjectData.getClosestTrajectoryTo(goldStandard.getTrials().get(trialID).getStartTime());

			if(null == subjectTrajectory) {
				// Some error occurred while parsing the file (we've had some students with blank Tobii files); skip this
				continue;
			}

			int targetIdx = trial.getTargetIdx();
			Trajectory<TrackItFrame> goldTrajectory = trial.getTrajectories().get(targetIdx);

			if(recordMap != null) {
				recordMap.put(trialID, new ArrayList<Double>());
			}

			SingleRunScore record = calcScore(goldTrajectory,
					subjectTrajectory, 
					recordMap == null ? null : recordMap.get(trialID));

			// If the subject's eyes weren't tracked by Tobii enough, then nil the score
			if( ((double)record.getFrameCountOnTarget() / (double)record.getFrameCountOverall() ) < lookThreshold) {
				record.setScore(Double.NaN);
			}

			// Some scoring function implement secondary features, like thinking about non-target objectsp; put that stuff here
			calcFixationStats(record, trial, subjectTrajectory);
			
			scoreMap.put(trialID, record);


		}
		return scoreMap;
	}