class_docstr: An Analysis is the application of a particular pipeline of modules to a
  set of images to produce measurements.
  
  Multiprocessing for analyses is handled by multiple layers of threads and
  processes, to keep the GUI responsive and simplify the code.  Threads and
  processes are organized as below.  Display/Interaction requests and
  Exceptions are sent directly to the pipeline listener.
  
  +------------------------------------------------+
  |           CellProfiler GUI/WX thread           |
  |                                                |
  +- Analysis() methods down,  Events/Requests up -+
  |                                                |
  |       AnalysisRunner.interface() thread        |
  |                                                |
  +----------------  Queues  ----------------------+
  |                                                |
  |  AnalysisRunner.jobserver()/announce() threads |
  |                                                |
  +----------------------------------------------- +
  |              zmqrequest.Boundary()             |
  +---------------+----------------+---------------+
  |     Worker    |     Worker     |   Worker      |
  +---------------+----------------+---------------+
  
  Workers are managed by class variables in the AnalysisRunner.
docstr: Start the analysis runner
  
  analysis_event_callback - callback from runner to UI thread for
                            event progress and UI handlers
  
  num_workers - # of worker processes to instantiate, default is # of cores
  
  overwrite - True (default) to process all image sets, False to only
              process incomplete ones (or incomplete groups if grouping)
code: def start(
      self, analysis_event_callback, num_workers=None, overwrite=True
  ):
      """Start the analysis runner
  
      analysis_event_callback - callback from runner to UI thread for
                                event progress and UI handlers
  
      num_workers - # of worker processes to instantiate, default is # of cores
  
      overwrite - True (default) to process all image sets, False to only
                  process incomplete ones (or incomplete groups if grouping)
      """
      with self.runner_lock:
          assert not self.analysis_in_progress
          self.analysis_in_progress = uuid.uuid1().hex
  
          self.runner = Runner(
              self.analysis_in_progress,
              self.pipeline,
              self.initial_measurements_buf,
              analysis_event_callback,
          )
          self.runner.start(
              num_workers=num_workers, overwrite=overwrite
          )
          return self.analysis_in_progress
  
file_path: CellProfiler/src/subpackages/core/cellprofiler_core/analysis/_analysis.py
imports: import gc
  import threading
  import uuid
  from ._runner import Runner
  from ..measurement import Measurements
label_desc: Use image node_id 2 for calling the Analysis obj's underlying member method code with example usage: obj.start(analysis_event_callback, num_workers, overwrite) and returns: self