diff --git a/admin/tool/analytics/classes/output/invalid_analysables.php b/admin/tool/analytics/classes/output/invalid_analysables.php
index 0bb3902..28c861b 100644
--- a/admin/tool/analytics/classes/output/invalid_analysables.php
+++ b/admin/tool/analytics/classes/output/invalid_analysables.php
@@ -82,7 +82,7 @@ class invalid_analysables implements \renderable, \templatable {
         $enoughresults = false;
         $morepages = false;
         $results = array();
-        foreach ($analysables as $key => $analysable) {
+        foreach ($analysables as $analysable) {
 
             $validtraining = $this->model->get_target()->is_valid_analysable($analysable, true);
             if ($validtraining === true) {
@@ -117,8 +117,6 @@ class invalid_analysables implements \renderable, \templatable {
                 $morepages = true;
                 break;
             }
-
-            unset($analysables[$key]);
         }
 
         // Prepare the context object.
diff --git a/analytics/classes/analysis.php b/analytics/classes/analysis.php
index 46a0d2d..fb37c58 100644
--- a/analytics/classes/analysis.php
+++ b/analytics/classes/analysis.php
@@ -83,11 +83,18 @@ class analysis {
 
         list($analysables, $processedanalysables) = $this->get_sorted_analysables();
 
+        if ($this->includetarget) {
+            $action = 'training';
+        } else {
+            $action = 'prediction';
+        }
+        $analysables = $this->analyser->get_analysables_recordset($action);
+
         $inittime = time();
-        foreach ($analysables as $key => $analysable) {
+        foreach ($analysables as $analysable) {
 
             $analysableresults = $this->process_analysable($analysable);
-            if (!$analysableresults) {
+            if ($analysableresults) {
                 // This situation has been logged in process_analysable.
                 continue;
             }
@@ -120,8 +127,6 @@ class analysis {
                     break;
                 }
             }
-
-            unset($analysables[$key]);
         }
 
         return true;
diff --git a/analytics/classes/course.php b/analytics/classes/course.php
index 919f36b..2cb102b 100644
--- a/analytics/classes/course.php
+++ b/analytics/classes/course.php
@@ -137,7 +137,7 @@ class course implements \core_analytics\analysable {
      * @param int|\stdClass $course Course id
      * @return void
      */
-    public function __construct($course) {
+    public function __construct($course, ?\context $context = null) {
 
         if (is_scalar($course)) {
             $this->course = new \stdClass();
@@ -145,6 +145,10 @@ class course implements \core_analytics\analysable {
         } else {
             $this->course = $course;
         }
+
+        if ($context) {
+            $this->coursecontext = $context;
+        }
     }
 
     /**
diff --git a/analytics/classes/local/analyser/by_course.php b/analytics/classes/local/analyser/by_course.php
index bbda69a..7fdc8bf 100644
--- a/analytics/classes/local/analyser/by_course.php
+++ b/analytics/classes/local/analyser/by_course.php
@@ -38,6 +38,51 @@ abstract class by_course extends base {
     /**
      * Return the list of courses to analyse.
      *
+     * @return \core\dml\recordset_walk
+     */
+    public function get_analysables_recordset($action) {
+        global $DB;
+
+        $select = 'c.*, ' . context_helper::get_preload_record_columns_sql('ctx');
+
+        // Default to all system courses.
+        // if (!empty($this->options['filter'])) {
+        //     $courses = array();
+        //     foreach ($this->options['filter'] as $courseid) {
+        //         $courses[$courseid] = new \stdClass();
+        //         $courses[$courseid]->id = $courseid;
+        //     }
+        // }
+
+        $sql = "SELECT $select
+                  FROM {course} c
+                  JOIN {context} ctx ON (ctx.contextlevel = :contextlevel AND ctx.instanceid = c.id)
+             LEFT JOIN {analytics_used_analysables} aua ON aua.analysableid = c.id
+                 WHERE aua.modelid = :modelid AND aua.action = :action
+              ORDER BY aua.timeanalyzed DESC, c.sortorder ASC";
+        $params = ['contextlevel' => CONTEXT_COURSE, 'modelid' => $this->get_modelid(), 'action' => $action];
+
+        $recordset = $DB->get_recordset_sql($sql, $params);
+
+        if (!$recordset->valid()) {
+            $this->add_log(get_string('nocourses', 'analytics'));
+            return [];
+        }
+
+        return new \core\dml\recordset_walk($recordset, function($record) {
+
+            if ($record->id == SITEID) {
+                // TODO Check that this does not return an empty array item, but that it skips this item.
+                return false;
+            }
+            $context = \context_helper::preload_from_record($course);
+            return \core_analytics\course::instance($record, $context);
+        });
+    }
+
+    /**
+     * Return the list of courses to analyse.
+     *
      * @return \core_analytics\course[]
      */
     public function get_analysables() {
diff --git a/analytics/classes/manager.php b/analytics/classes/manager.php
index c214bf7..136dc21 100644
--- a/analytics/classes/manager.php
+++ b/analytics/classes/manager.php
@@ -640,9 +640,10 @@ class manager {
                 continue;
             }
 
-            $analysableids = array_map(function($analysable) {
-                return $analysable->get_id();
-            }, $analysables);
+            $analysableids = [];
+            foreach ($analysables as $analysable) {
+                $analysableids[] = $analysable->get_id();
+            }
 
             list($notinsql, $params) = $DB->get_in_or_equal($analysableids, SQL_PARAMS_NAMED, 'param', false);
             $params['modelid'] = $model->get_id();
