def __init__(self, data_dir, log_level=None, scope_host='127.0.0.1', dry_run=False):
    'Setup the basic code to take a single timepoint from a timecourse experiment.\n\n        Parameters:\n            data_dir: directory where the data and metadata-files should be read/written.\n            io_threads: number of threads to use to save image data out.\n            loglevel: level from logging library at which to log information to the\n                logfile in data_dir. (Subclasses can log information with self.logger)\n                If not specified, fall back to the class attribute LOG_LEVEL. This\n                allows a subclass to set a default log level, which still can be\n                over-ridden from the command line.\n            scope_host: IP address to connect to the scope server. If None, run without\n                a scope server.\n            dry_run: if True, do not write any files (including log files; log entries\n                will be printed to the console).\n        '
    self.data_dir = pathlib.Path(data_dir).resolve()
    self.experiment_metadata_path = (self.data_dir / 'experiment_metadata.json')
    with self.experiment_metadata_path.open('r') as f:
        self.experiment_metadata = json.load(f)
    self.experiment_metadata['node'] = platform.node()
    self.positions = self.experiment_metadata['positions']
    self.skip_positions = set()
    annotations = load_data.read_annotations(self.data_dir)
    for position in self.positions.keys():
        if (position in annotations):
            (position_annotations, timepoint_annotations) = annotations[position]
            if position_annotations.get('exclude'):
                self.skip_positions.add(position)
            else:
                for annotation in timepoint_annotations.values():
                    if (annotation.get('stage') == 'dead'):
                        self.skip_positions.add(position)
                        break
    if (scope_host is not None):
        from .. import scope_client
        self.scope = scope_client.ScopeClient(scope_host)
        if hasattr(self.scope, 'camera'):
            self.scope.camera.return_to_default_state()
    else:
        self.scope = None
    self.write_files = (not dry_run)
    self.logger = log_util.get_logger(str(data_dir))
    if (log_level is None):
        log_level = self.LOG_LEVEL
    elif isinstance(log_level, str):
        log_level = getattr(logging, log_level)
    self.logger.setLevel(log_level)
    if self.write_files:
        self.image_io = threaded_io.ThreadedIO(self.IO_THREADS, self.MAX_IO_JOBS)
        handler = logging.FileHandler(str((self.data_dir / 'acquisitions.log')))
    else:
        self.image_io = DummyIO(self.logger)
        handler = logging.StreamHandler()
    handler.setFormatter(log_util.get_formatter())
    self.logger.addHandler(handler)
    self._job_thread = None
Setup the basic code to take a single timepoint from a timecourse experiment.

Parameters:
    data_dir: directory where the data and metadata-files should be read/written.
    io_threads: number of threads to use to save image data out.
    loglevel: level from logging library at which to log information to the
        logfile in data_dir. (Subclasses can log information with self.logger)
        If not specified, fall back to the class attribute LOG_LEVEL. This
        allows a subclass to set a default log level, which still can be
        over-ridden from the command line.
    scope_host: IP address to connect to the scope server. If None, run without
        a scope server.
    dry_run: if True, do not write any files (including log files; log entries
        will be printed to the console).
def __init__(self, data_dir, log_level=None, scope_host='127.0.0.1', dry_run=False):
    'Setup the basic code to take a single timepoint from a timecourse experiment.\n\n        Parameters:\n            data_dir: directory where the data and metadata-files should be read/written.\n            io_threads: number of threads to use to save image data out.\n            loglevel: level from logging library at which to log information to the\n                logfile in data_dir. (Subclasses can log information with self.logger)\n                If not specified, fall back to the class attribute LOG_LEVEL. This\n                allows a subclass to set a default log level, which still can be\n                over-ridden from the command line.\n            scope_host: IP address to connect to the scope server. If None, run without\n                a scope server.\n            dry_run: if True, do not write any files (including log files; log entries\n                will be printed to the console).\n        '
    self.data_dir = pathlib.Path(data_dir).resolve()
    self.experiment_metadata_path = (self.data_dir / 'experiment_metadata.json')
    with self.experiment_metadata_path.open('r') as f:
        self.experiment_metadata = json.load(f)
    self.experiment_metadata['node'] = platform.node()
    self.positions = self.experiment_metadata['positions']
    self.skip_positions = set()
    annotations = load_data.read_annotations(self.data_dir)
    for position in self.positions.keys():
        if (position in annotations):
            (position_annotations, timepoint_annotations) = annotations[position]
            if position_annotations.get('exclude'):
                self.skip_positions.add(position)
            else:
                for annotation in timepoint_annotations.values():
                    if (annotation.get('stage') == 'dead'):
                        self.skip_positions.add(position)
                        break
    if (scope_host is not None):
        from .. import scope_client
        self.scope = scope_client.ScopeClient(scope_host)
        if hasattr(self.scope, 'camera'):
            self.scope.camera.return_to_default_state()
    else:
        self.scope = None
    self.write_files = (not dry_run)
    self.logger = log_util.get_logger(str(data_dir))
    if (log_level is None):
        log_level = self.LOG_LEVEL
    elif isinstance(log_level, str):
        log_level = getattr(logging, log_level)
    self.logger.setLevel(log_level)
    if self.write_files:
        self.image_io = threaded_io.ThreadedIO(self.IO_THREADS, self.MAX_IO_JOBS)
        handler = logging.FileHandler(str((self.data_dir / 'acquisitions.log')))
    else:
        self.image_io = DummyIO(self.logger)
        handler = logging.StreamHandler()
    handler.setFormatter(log_util.get_formatter())
    self.logger.addHandler(handler)
    self._job_thread = None