class_docstr: Tracks pipeline progress and estimates time to completion 
docstr: Return our best estimate of the remaining duration, or None
  if we have no bases for guessing.
docstr_tok: ["Return","our","best","estimate","of","the","remaining","duration",",","or","None","if","we","have","no","bases","for","guessing","."]
code: def remaining_time(self):
      """Return our best estimate of the remaining duration, or None
      if we have no bases for guessing."""
      if self.end_times is None:
          return (
              2 * self.elapsed_time()
          )  # We have not started the first module yet
      else:
          module_index = self.current_module.module_num - 1
          index = self.image_set_index * self.num_modules + module_index
          durations = (
              self.end_times[1:] - self.end_times[:-1]
          ).reshape(self.num_image_sets, self.num_modules)
          per_module_estimates = numpy.zeros(self.num_modules)
          per_module_estimates[:module_index] = numpy.median(
              durations[: self.image_set_index + 1, :module_index], 0
          )
          current_module_so_far = (
              self.elapsed_time() - self.end_times[1 + index - 1]
          )
          if self.image_set_index > 0:
              per_module_estimates[module_index:] = numpy.median(
                  durations[: self.image_set_index, module_index:], 0
              )
              per_module_estimates[module_index] = max(
                  per_module_estimates[module_index],
                  current_module_so_far,
              )
          else:
              # Guess that the modules that haven't finished yet are
              # as slow as the slowest one we've seen so far.
              per_module_estimates[module_index] = current_module_so_far
              per_module_estimates[
                  module_index:
              ] = per_module_estimates[: module_index + 1].max()
          per_module_estimates[:module_index] *= (
              self.num_image_sets - self.image_set_index - 1
          )
          per_module_estimates[module_index:] *= (
              self.num_image_sets - self.image_set_index
          )
          per_module_estimates[module_index] -= current_module_so_far
          return per_module_estimates.sum()
  
file_path: CellProfiler/src/frontend/cellprofiler/gui/preferences_view/_progress_watcher.py
imports: import time
  import numpy
  import wx
label_desc: Use image node_id 11 for calling the ProgressWatcher obj's underlying member method code with example usage: obj.remaining_time() and returns: unknown, per_module_estimates