Observing mode processing mode of numina.

def run_reduce(datastore, obsid, copy_files=True):
    """Observing mode processing mode of numina."""

    request = 'reduce'
    request_params = {}

    rb = ReductionBlock()
    rb.id = obsid

    request_params['oblock_id'] = rb.id
    request_params["pipeline"] = rb.pipeline
    request_params["instrument_configuration"] = rb.instrument_configuration

    logger_control = dict(
        default=__name__,
        logfile='processing.log',
        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
        enabled=True
    )
    request_params['logger_control'] = logger_control

    task = datastore.backend.new_task(request, request_params)
    task.request = request
    task.request_params = request_params

    task.request_runinfo['runner'] = 'numina'
    task.request_runinfo['runner_version'] = __version__

    _logger.info("procesing OB with id={}".format(obsid))
    workenv = datastore.create_workenv(task)

    task.request_runinfo["results_dir"] = workenv.resultsdir_rel
    task.request_runinfo["work_dir"] = workenv.workdir_rel

    # Roll back to cwd after leaving the context
    with working_directory(workenv.datadir):

        obsres = datastore.backend.obsres_from_oblock_id(obsid, configuration=rb.instrument_configuration)

        _logger.debug("pipeline from CLI is %r", rb.pipeline)
        pipe_name = rb.pipeline
        obsres.pipeline = pipe_name
        recipe = datastore.backend.search_recipe_from_ob(obsres)
        _logger.debug('recipe class is %s', recipe.__class__)

        # Enable intermediate results by default
        _logger.debug('enable intermediate results')
        recipe.intermediate_results = True

        # Update runinfo
        _logger.debug('update recipe runinfo')
        recipe.runinfo['runner'] = 'numina'
        recipe.runinfo['runner_version'] = __version__
        recipe.runinfo['task_id'] = task.id
        recipe.runinfo['data_dir'] = workenv.datadir
        recipe.runinfo['work_dir'] = workenv.workdir
        recipe.runinfo['results_dir'] = workenv.resultsdir

        _logger.debug('recipe created')

        try:
            rinput = recipe.build_recipe_input(obsres, datastore.backend)
        except (ValueError, numina.exceptions.ValidationError) as err:
            _logger.error("During recipe input construction")
            _logger.error("%s", err)
            raise
            # sys.exit(0)

        _logger.debug('recipe input created')
        # Show the actual inputs
        for key in recipe.requirements():
            v = getattr(rinput, key)
            _logger.debug("recipe requires %r, value is %s", key, v)

        for req in recipe.products().values():
            _logger.debug('recipe provides %s, %s', req.type.__class__.__name__, req.description)

    # Load recipe control and recipe parameters from file
    task.request_runinfo['instrument'] = obsres.instrument
    task.request_runinfo['mode'] = obsres.mode
    task.request_runinfo['recipe_class'] = recipe.__class__.__name__
    task.request_runinfo['recipe_fqn'] = fully_qualified_name(recipe.__class__)
    task.request_runinfo['recipe_version'] = recipe.__version__

    # Copy files
    if copy_files:
        _logger.debug('copy files to work directory')
        workenv.sane_work()
        workenv.copyfiles_stage1(obsres)
        workenv.copyfiles_stage2(rinput)
        workenv.adapt_obsres(obsres)

    completed_task = run_recipe(recipe=recipe, task=task, rinput=rinput,
                                workenv=workenv, logger_control=logger_control)

    datastore.store_task(completed_task)
    return completed_task