docs: def run(self, data_dir=None):
  
          """
          Note: this function will check the experiments directory for a
          special file, scheduler.info, that details how often each
          experiment should be run and the last time the experiment was
          run. If the time since the experiment was run is shorter than
          the scheduled interval in seconds, then the experiment will
          not be run.
  
          :param data_dir:
          :return:
          """
          # XXX: android build needs this. refactor
          if data_dir:
              centinel_home = data_dir
              self.config['dirs']['results_dir'] = os.path.join(centinel_home,
                                                                'results')
  
          logging.info('Centinel started.')
  
          if not os.path.exists(self.config['dirs']['results_dir']):
              logging.warn("Creating results directory in "
                           "%s" % (self.config['dirs']['results_dir']))
              os.makedirs(self.config['dirs']['results_dir'])
          logging.debug("Results directory: %s" % (self.config['dirs']['results_dir']))
  
          # load scheduler information
          sched_filename = os.path.join(self.config['dirs']['experiments_dir'],
                                        'scheduler.info')
  
          logging.debug("Loading scheduler file.")
          sched_info = {}
          if os.path.exists(sched_filename):
              with open(sched_filename, 'r') as file_p:
                  try:
                      sched_info = json.load(file_p)
                  except Exception as exp:
                      logging.error("Failed to load the "
                                    "scheduler: %s" % str(exp))
                      return
  
          logging.debug("Scheduler file loaded.")
  
          logging.debug("Processing the experiment schedule.")
          for name in sched_info:
  
              # check if we should preempt on the experiment (if the
              # time to run next is greater than the current time) and
              # store the last run time as now
              #
              # Note: if the experiment is not in the scheduler, then it
              # will not be run at all.
              run_next = sched_info[name]['last_run']
              run_next += sched_info[name]['frequency']
              if run_next > time.time():
                  run_next_str = datetime.fromtimestamp(long(run_next))
                  logging.debug("Skipping %s, it will "
                                "be run on or after %s." % (name, run_next_str))
                  continue
  
              # backward compatibility with older-style scheduler
              if 'python_exps' not in sched_info[name]:
                  self.run_exp(name=name)
              else:
                  exps = sched_info[name]['python_exps'].items()
                  for python_exp, exp_config in exps:
                      logging.debug("Running %s." % python_exp)
                      self.run_exp(name=python_exp, exp_config=exp_config, schedule_name=name)
                      logging.debug("Finished running %s." % python_exp)
              sched_info[name]['last_run'] = time.time()
  
          logging.debug("Updating timeout values in scheduler.")
          # write out the updated last run times
          with open(sched_filename, 'w') as file_p:
              json.dump(sched_info, file_p, indent=2,
                        separators=(',', ': '))
  
          self.consolidate_results()
  
          logging.info("Finished running experiments. "
                       "Look in %s for results." % (self.config['dirs']['results_dir']))