Example #1
0
def experiment_list(request, instrument):
    """
        Return the list of experiments for a given instrument
        @param request: request object
        @param instrument: instrument name
    """
    
    breadcrumbs = Breadcrumbs("home", reverse('home'))
    breadcrumbs.append("%s catalog"%instrument.lower())
    
    experiments = get_experiments(instrument.upper())
    
    logger.debug("Catalog: %s : len(experiment list) = %s for %s"%(inspect.stack()[0][3],len(experiments),instrument))
    
    template_values = {'experiments': experiments,
                       'instrument': instrument,
                       'title': '%s experiments' % instrument.upper(),
                       'breadcrumbs': breadcrumbs}
    if len(experiments)==0:
        template_values['user_alert'] = ['Could not get experiment list from the catalog']
    template_values = remote_view_util.fill_template_values(request, **template_values)
    template_values = catalog_view_util.fill_template_values(request, **template_values)
    template_values = users_view_util.fill_template_values(request, **template_values)
    return render_to_response('catalog/experiment_list.html',
                              template_values,
                              context_instance=RequestContext(request))
Example #2
0
def reduction_home(request, instrument_name):
    """
        Home page for the <instrument_name> reduction.
        This will show a list of experiments for which the user have set up reductions.
        @param request: request object
    """
    logger.debug("Reduction: %s instrument_name=%s"%(inspect.stack()[0][3],instrument_name))
    
    instrument = get_object_or_404(Instrument, name=instrument_name)
    
    experiments = Experiment.objects.experiments_for_instrument(instrument, owner=request.user)
    
    breadcrumbs = Breadcrumbs()
    breadcrumbs.append("%s reduction"%instrument_name)    
    
    template_values = {'title': str.capitalize(str(instrument_name)) + ' Reduction',
                       'experiments':experiments,
                       'breadcrumbs': breadcrumbs,
                       'instrument' : instrument_name, }
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    
    logger.debug(pprint.pformat(template_values))
    return render_to_response('reduction/reduction_home.html',
                              template_values,
                              context_instance=RequestContext(request))
Example #3
0
def download_autoreduced(request, instrument, ipts):
    """
        Download all the auto-reduced files for a given experiment.
        @param request: request object
        @param instrument: instrument name
        @param ipts: experiment name
    """
    # Start a new transaction
    transaction = remote_view_util.transaction(request, start=True)
    if transaction is None:
        
        breadcrumbs = Breadcrumbs()
        breadcrumbs.append_experiment_list(instrument)
        
        template_values = {'message':"Could not connect to Fermi and establish transaction",
                           'back_url': reverse('catalog_experiments', args=[instrument]),
                           'breadcrumbs': breadcrumbs,}
        template_values = remote_view_util.fill_template_values(request, **template_values)
        template_values = catalog_view_util.fill_template_values(request, **template_values)
        return render_to_response('remote/failed_connection.html',
                                  template_values)

    file_name = "%s_%s.zip" % (instrument.upper(), ipts)
    code =  'import os\n'
    code += 'import zipfile\n'
    code += 'output_zip_file = zipfile.ZipFile("%s", "w")\n' % file_name
    code += 'for f in os.listdir("/SNS/%s/%s/shared/autoreduce"):\n' % (instrument.upper(), ipts.upper())
    code += '    output_zip_file.write("/SNS/%s/%s/shared/autoreduce/"+f, f)\n' % (instrument.upper(), ipts.upper())
    code += 'output_zip_file.close()\n'
    jobID = remote_view_util.submit_job(request, transaction, code)

    return redirect(reverse('catalog_download_link', args=[jobID, file_name]))
Example #4
0
def reduction_jobs(request, instrument_name):
    """
        Return a list of the remote reduction jobs.
        The jobs are those that are owned by the user and have an
        entry in the database.
        
        @param request: request object
    """
    logger.debug("Reduction: %s instrument_name=%s"%(inspect.stack()[0][3],instrument_name))
    
    instrument_name = str(instrument_name).lower()
    
    jobs = RemoteJob.objects.filter(transaction__owner=request.user).filter(reduction__instrument__name=instrument_name )
    status_data = []
    for job in jobs:
        if not job.transaction.is_active or job.reduction.get_config() is not None:
            continue
        j_data = {'remote_id': job.remote_id,
                  'id': job.pk,
                  'name': job.reduction.name,
                  'reduction_id': job.reduction.id,
                  'start_date': job.transaction.start_time,
                  'data': job.reduction.data_file,
                  'trans_id': job.transaction.trans_id,
                  'experiments': job.reduction.get_experiments()
                 }
        status_data.append(j_data)
    
    # Get config jobs
    config_jobs = RemoteJobSet.objects.filter(transaction__owner=request.user).filter(configuration__instrument__name=instrument_name )
    config_data = []
    for job in config_jobs:
        if not job.transaction.is_active:
            continue
        j_data = {'id': job.id,
                  'config_id': job.configuration.id,
                  'name': job.configuration.name,
                  'trans_id': job.transaction.trans_id,
                  'experiments': job.configuration.get_experiments()
                 }
        config_data.append(j_data)
        
    breadcrumbs = Breadcrumbs()
    breadcrumbs.append_reduction(str.lower(str(instrument_name)))
    breadcrumbs.append("jobs")
    template_values = {'status_data': status_data,
                       'config_data': config_data,
                       'back_url': request.path,
                       'breadcrumbs': breadcrumbs,
                       'instrument' : instrument_name, }
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    logger.debug(pprint.pformat(template_values))   
    return render_to_response('%s/reduction_jobs.html' % instrument_name,
                              template_values,
                              context_instance=RequestContext(request))
Example #5
0
def configuration_query(request, remote_set_id, instrument_name):
    """
        Query all jobs in a job set
        @param request: request object
        @param remote_id: pk of RemoteJobSet object
    """
    logger.debug("%s remote_set_id=%s"%(inspect.stack()[0][3],remote_set_id))
    
    instrument_name_lowercase = str.lower(str(instrument_name))
    instrument_name_capitals = str.capitalize(str(instrument_name))
    job_set = get_object_or_404(RemoteJobSet, pk=remote_set_id)
    
    breadcrumbs = Breadcrumbs()
    breadcrumbs.append('%s reduction'%instrument_name_lowercase,reverse('reduction_home',
                                                  kwargs={'instrument_name': instrument_name_lowercase }))
    breadcrumbs.append_configuration(instrument_name_lowercase, job_set.configuration.id)
    breadcrumbs.append('jobs',reverse('reduction_jobs', kwargs={'instrument_name': instrument_name_lowercase}))
    breadcrumbs.append("job results")
    
    template_values = {'remote_set_id': remote_set_id,
                       'configuration_title': job_set.configuration.name,
                       'configuration_id': job_set.configuration.id,
                       'breadcrumbs': breadcrumbs,
                       'title': '%s job results'%instrument_name_capitals,
                       'trans_id': job_set.transaction.trans_id,
                       'job_directory': job_set.transaction.directory,
                       'back_url': request.path,
                       'instrument': instrument_name_lowercase}
    
    # Get status of each job
    job_set_info = []
    first_job = None
    for item in job_set.jobs.all():
        job_info = remote.view_util.query_remote_job(request, item.remote_id)
        if job_info is not None:
            first_job = item
            job_info['reduction_name'] = item.reduction.name
            job_info['reduction_id'] = item.reduction.id # same as remote_job_remote_id!!
            job_info['id'] = item.id
            job_info['remote_id'] = item.remote_id
            job_info['parameters'] = item.get_data_dict()
            job_set_info.append(job_info)
    template_values['job_set_info'] = job_set_info
    
    # Show list of files in the transaction
    template_values['job_files'] = remote.view_util.query_files(request, job_set.transaction.trans_id)
    logger.debug(pprint.pformat(template_values['job_files']))
    
    # I(q) plots
    inst_view_util = view_util.import_module_from_app(instrument_name_lowercase,'view_util')
    template_values = inst_view_util.set_into_template_values_plots(template_values, request, first_job)
    # Link to download all I(q) files
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    
    logger.debug(pprint.pformat(template_values))
    
    return render_to_response('%s/configuration_query.html'%instrument_name_lowercase, template_values,
                              context_instance=RequestContext(request))
Example #6
0
def reduction_submit(request, reduction_id, instrument_name):
    """
        Submit a reduction script to Fermi.

        @param request: request object
        @param reduction_id: pk of the ReductionProcess object
    """
    
    logger.debug("Reduction: %s instrument_name=%s"%(inspect.stack()[0][3],instrument_name))
    
    instrument_name_lowercase = str.lower(str(instrument_name))
    instrument_forms = view_util.import_module_from_app(instrument_name_lowercase,'forms')
    
    # TODO: Make sure the submission errors are clearly reported
    reduction_proc = get_object_or_404(ReductionProcess, pk=reduction_id, owner=request.user)

    # Start a new transaction
    transaction = remote.view_util.transaction(request, start=True)
    if transaction is None:
        
        breadcrumbs = Breadcrumbs()
        breadcrumbs.append_reduction(instrument_name_lowercase)
        breadcrumbs.append_reduction_options(instrument_name_lowercase, reduction_id)
        
        messages.add_message(request, messages.ERROR, "Could not connect to Fermi and establish transaction.")
        template_values = {'back_url': reverse('reduction_options',
                                               kwargs={'reduction_id' : reduction_id, 'instrument_name': instrument_name_lowercase}),
                           'breadcrumbs': breadcrumbs, }
        template_values = reduction_server.view_util.fill_template_values(request, **template_values)
        logger.debug(pprint.pformat(template_values))
        return render_to_response('remote/failed_connection.html', template_values,
                                  context_instance=RequestContext(request))

    data = instrument_forms.ReductionOptions.data_from_db(request.user, reduction_id)
    code = instrument_forms.ReductionOptions.as_mantid_script(data, transaction.directory)
    jobID = remote.view_util.submit_job(request, transaction, code)
    if jobID is not None:
        job = RemoteJob(reduction=reduction_proc,
                        remote_id=jobID,
                        properties=reduction_proc.properties,
                        transaction=transaction)
        job.save()
        logger.debug("Created a RemoteJob: %s",job)
    
    messages.add_message(request, messages.SUCCESS, 
                         message="Job %s sucessfully submitted. <a href='%s' class='message-link'>Click to see the results this job </a>."%
                                     (job.id, reverse('reduction_query', kwargs={'remote_job_id' : job.id, 'instrument_name' : instrument_name_lowercase})))
    
    return redirect(reverse('reduction_options',
                                  kwargs={'reduction_id' : reduction_id, 
                                          'instrument_name': instrument_name_lowercase}))
Example #7
0
def reduction_script(request, reduction_id, instrument_name):
    """
        Display a script representation of a reduction process.
        
        @param request: request object
        @param reduction_id: pk of the ReductionProcess object
    """
    
    logger.debug("Reduction: %s instrument_name=%s"%(inspect.stack()[0][3],instrument_name))
    
    instrument_name_lowercase = str.lower(str(instrument_name))
    
    instrument_forms = view_util.import_module_from_app(instrument_name_lowercase,'forms')
    
    data = instrument_forms.ReductionOptions.data_from_db(request.user, reduction_id)
    
    breadcrumbs = Breadcrumbs()
    breadcrumbs.append_reduction(instrument_name_lowercase)
    breadcrumbs.append("reduction %s"%reduction_id,".")
    breadcrumbs.append("script")
    
    template_values = {'reduction_name': data['reduction_name'],
                       'breadcrumbs': breadcrumbs,
                       'code': instrument_forms.ReductionOptions.as_mantid_script(data) }
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    logger.debug(pprint.pformat(template_values))
    return render_to_response('reduction/reduction_script.html', template_values,
                              context_instance=RequestContext(request))
Example #8
0
def adjust_2d(request, plot_id):
    """
        Update the layout parameters for a given 1D plot
        
        @param request: http request object
        @param plot_id: pk of the Plot1D entry
        
    """
    plot_2d = get_object_or_404(Plot2D, pk=plot_id, owner=request.user)
    breadcrumbs = Breadcrumbs()
    breadcrumbs.append("plotting")
    
    template_values = {'plot_2d': plot_2d,
                       'breadcrumbs': breadcrumbs}
    if 'back' in request.GET:
        template_values['back_url'] = request.GET['back']
        
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    return render_to_response('plotting/adjust_2d.html',
                              template_values)
Example #9
0
def reduction_query(request, remote_job_id, instrument_name):
    """
        Show status of a given remote job.
        
        @param request: request object
        @param remote_job_id: pk of the RemoteJob object
        
    """
    instrument_name_lowercase = str.lower(str(instrument_name))
    instrument_name_capitals = str.capitalize(str(instrument_name))
    
    logger.debug("Views: %s job_id=%s"%(inspect.stack()[0][3],remote_job_id))
    
    remote_job = get_object_or_404(RemoteJob, pk=remote_job_id)

    breadcrumbs = Breadcrumbs()
    breadcrumbs.append('%s reduction'%instrument_name_lowercase,reverse('reduction_home',
                                                  kwargs={'instrument_name': instrument_name_lowercase }))
    breadcrumbs.append_reduction_options(instrument_name_lowercase, remote_job.reduction.id )
    breadcrumbs.append('jobs',reverse('reduction_jobs',
                                      kwargs={'instrument_name': instrument_name_lowercase }))
    breadcrumbs.append("job %s" % remote_job_id)
    
    template_values = {'remote_job': remote_job,
                       'remote_job_id' : remote_job.pk,
                       'parameters': remote_job.get_data_dict(),
                       'reduction_id': remote_job.reduction.id,
                       'breadcrumbs': breadcrumbs,
                       'back_url': request.path,
                       'instrument': instrument_name_lowercase}
    template_values = remote.view_util.fill_job_values(request, remote_job.remote_id, **template_values)
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    template_values['title'] = "%s job results"%instrument_name_capitals
    
    # Go through the files and find data to plot
    if 'job_files' in template_values and 'trans_id' in template_values:
        ints_view_util = view_util.import_module_from_app(instrument_name_lowercase,'view_util')
        template_values = ints_view_util.set_into_template_values_job_files(template_values, request, remote_job)

    logger.debug(pprint.pformat(template_values))
    return render_to_response('%s/reduction_query.html'%instrument_name,
                              template_values,
                              context_instance=RequestContext(request))
Example #10
0
def perform_login(request):
    """
        Perform user authentication
    """
    user = None  
    login_failure = None
    if request.method == 'POST':
        username = request.POST["username"]
        password = request.POST["password"]
        user = authenticate(username=username, password=password)
        if user is not None and not user.is_anonymous():
            login(request,user)
        else:
            login_failure = "Invalid username or password"
    
    if request.user.is_authenticated():
        # Try to authenticate with Fermi
        remote_view_util.authenticate(request)
        
        # If we came from a given page and just needed 
        # authentication, go back to that page.
        if "next" in request.GET:
            redirect_url = request.GET["next"]
            return redirect(redirect_url)
        return redirect(reverse(settings.LANDING_VIEW))
    else:
        # Breadcrumbs
        breadcrumbs = Breadcrumbs()
        breadcrumbs.append("login")
        
        template_values = {'breadcrumbs': breadcrumbs,
                           'login_failure': login_failure}
        template_values = fill_template_values(request, **template_values)
        
        return render_to_response('users/authenticate.html', template_values,
                              context_instance=RequestContext(request))
Example #11
0
def experiment_run_list(request, instrument, ipts):
    """
        Return a list of runs for a given experiment with the reduce link.
        The reduce link will generate a JQuery Dialog unique per instrument
        The configuration of the Dialog Box are in <instrument_name>.__init__.py
        under the funtion get_reduction_dialog_settings(ipts, run)
        @param request: request object
        @param instrument: instrument name
        @param ipts: experiment name
    """
    
    logger.debug("Catalog: %s : instrument = %s, IPTS = %s"%(inspect.stack()[0][3],instrument,ipts))
    
    
    
    breadcrumbs = Breadcrumbs("home", reverse('catalog'))
    breadcrumbs.append_experiment_list(instrument)
    breadcrumbs.append(ipts.lower())
        
    template_values = {'instrument': instrument,
                       'experiment': ipts,
                       'title': '%s %s' % (instrument.upper(), ipts.upper()),
                       'breadcrumbs': breadcrumbs}

    if users_view_util.is_experiment_member(request, instrument, ipts) is False:
        template_values['user_alert'] = ["You do not have access to this experiment data."]
    else:
        runs = get_ipts_runs(instrument.upper(), ipts)
        template_values['run_data'] = runs
        if len(runs) == 0:
            template_values['user_alert'] = ['No runs were found for instrument %s experiment %s' % (instrument, ipts)]
    # Fill in Fermi auth values, login info,
    template_values = remote_view_util.fill_template_values(request, **template_values)
    template_values = catalog_view_util.fill_template_values(request, **template_values)
    template_values = users_view_util.fill_template_values(request, **template_values)
    return render_to_response('catalog/experiment_run_list.html', template_values)
Example #12
0
def experiment(request, ipts, instrument_name):
    """
        List of reductions and configurations for a given experiment
        @param request: request object
        @param ipts: experiment name
        
        #TODO create new reduction using a pre-existing one as a template
    """
    
    logger.debug("Reduction: %s instrument_name=%s"%(inspect.stack()[0][3],instrument_name))
    
    instrument_name_capitals = str.capitalize(str(instrument_name))
    instrument_name_lowercase = str.lower(str(instrument_name))
    
    # Get experiment object
    uncategorized = Experiment.objects.get_uncategorized(instrument_name)
    try:
        experiment_obj = Experiment.objects.get(name=ipts)
    except:
        experiment_obj = uncategorized
    
    IS_UNCATEGORIZED = experiment_obj.is_uncategorized()
    
    #RIC: Don't understand this one!
    reduction_start_form = forms.ReductionStart(request.GET)

    icat_ipts = {}
    if not IS_UNCATEGORIZED:
        icat_ipts = get_ipts_info(str.capitalize(str(instrument_name)), ipts)

    # Get all the user's reductions
    red_list = []
    if 'run_number' in request.GET:
        red_list = ReductionProcess.objects.filter(owner=request.user,
                                                   data_file__contains=request.GET['run_number'])
        if len(red_list) == 0:
            create_url = reverse('reduction_options',
                                  kwargs={'instrument_name': instrument_name_lowercase})
            create_url += '?reduction_name=Reduction for r%s' % request.GET['run_number']
            create_url += '&expt_id=%d' % experiment_obj.id
            create_url += '&data_file=%s' % request.GET['run_number']
            return redirect(create_url)
    else:
        for item in ReductionProcess.objects.filter(owner=request.user,
                                                    experiments=experiment_obj).order_by('data_file'):
            if not item in red_list:
                red_list.append(item)

    reductions = []
    for r in red_list:
        data_dict = r.get_data_dict()
        data_dict['id'] = r.id
        data_dict['config'] = r.get_config()
        # For this reduction_process (r) check if there more more jobs, if so get the most recent!
        latest_job = view_util.get_latest_job(request, r)
        if latest_job is not None:
            data_dict['completed_job'] = reverse('reduction_query',
                                                 kwargs={'remote_job_id' : latest_job.pk,
                                                         'instrument_name': instrument_name_lowercase })
        try:
            run_id = int(data_dict['data_file'])
            data_dict['webmon_url'] = "https://monitor.sns.gov/report/%s/%s/" %(instrument_name,run_id)
        except:
            pass
        reductions.append(data_dict)
        
    # Get all user configurations
    config_list = ReductionConfiguration.objects.filter(owner=request.user,
                                                        experiments=experiment_obj).order_by('name')
    configurations = []
    for item in config_list:
        data_dict = item.get_data_dict()
        data_dict['id'] = item.id
        latest_jobs = RemoteJobSet.objects.filter(configuration=item)
        if len(latest_jobs) > 0:
            latest_job = latest_jobs.latest('id')
            data_dict['latest_job'] = latest_job.id
            # data_dict['latest_job'] = reverse('eqsans.views.configuration_query', args=[latest_job.id])
        configurations.append(data_dict)
    
    breadcrumbs = Breadcrumbs()
    breadcrumbs.append_reduction(instrument_name_lowercase)
    breadcrumbs.append(ipts.lower())
    
    template_values = {'reductions': reductions,
                       'configurations': configurations,
                       'title': '%s %s' % (instrument_name_capitals, ipts),
                       'breadcrumbs': breadcrumbs,
                       'ipts_number': ipts,
                       'back_url': reverse('reduction_experiment', kwargs={'ipts' : ipts, 'instrument_name': instrument_name_lowercase }),
                       'icat_info': icat_ipts,
                       'form': reduction_start_form,
                       'is_categorized': not IS_UNCATEGORIZED,
                       'instrument' : instrument_name_lowercase, }
    if 'icat_error' in icat_ipts:
        template_values['user_alert'] = [icat_ipts['icat_error']]
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
#     logger.debug(pprint.pformat(configurations))
#     logger.debug(pprint.pformat(reductions))
    logger.debug(pprint.pformat(template_values))
    return render_to_response('%s/experiment.html' % instrument_name_lowercase,
                              template_values,
                              context_instance=RequestContext(request))
Example #13
0
def configuration_options(request, instrument_name, config_id=None):
    """
        Show the reduction properties for a given configuration,
        along with all the reduction jobs associated with it.
        Called when clicked Reduce->Batch Button, or new configuration
        
        @param request: The request object
        @param config_id: The ReductionConfiguration pk
    """
    
    logger.debug("configuration_options: %s"%inspect.stack()[0][3])
#     logger.debug("************************** POST")
#     l = request.POST.items()
#     l.sort()
#     logger.debug(pprint.pformat(l))
#     logger.debug("************************** GET")
#     l = request.GET.items()
#     l.sort()
#     logger.debug(pprint.pformat(l))
            
    instrument_name_capitals = str(instrument_name).upper()
    instrument_name_lowercase = str(instrument_name).lower()
    instrument_forms = view_util.import_module_from_app(instrument_name_lowercase,'forms')
    
    template_values = {}
    forms_handler = instrument_forms.ConfigurationFormHandler(request,config_id)
    
    # The list of relevant experiments will be displayed on the page
    expt_list = None
    job_list = None

    # Deal with data submission
    if request.method == 'POST':
        if forms_handler.are_forms_valid():
            config_id = forms_handler.save_forms()
            if config_id is not None:
                return redirect(reverse('configuration_options',
                                        kwargs={'config_id' : config_id,
                                                'instrument_name' : instrument_name_lowercase}))
    else:
        # Deal with the case of creating a new configuration
        if config_id is not None:
            reduction_config = get_object_or_404(ReductionConfiguration, pk=config_id, owner=request.user)
            expt_list = reduction_config.experiments.all()
            job_list = RemoteJobSet.objects.filter(configuration=reduction_config)

    breadcrumbs = Breadcrumbs()
    breadcrumbs.append_reduction(instrument_name_lowercase)
    if config_id is not None:
        breadcrumbs.append("configuration %s" % config_id)
    else:
        breadcrumbs.append("new configuration")

    # ICAT info url
    icat_url = reverse('catalog_run_info', args=[instrument_name_capitals, '0000'])
    icat_url = icat_url.replace('/0000', '')
    # TODO: add New an Save-As functionality
    template_values.update({'config_id': config_id,
                       'expt_list': expt_list,
                       'existing_job_sets': job_list,
                       'title': '%s Reduction' % instrument_name_capitals,
                       'breadcrumbs': breadcrumbs,
                       'icat_url': icat_url,
                       'instrument' : instrument_name, })
    
    template_values.update( forms_handler.get_forms())
    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    
    logger.debug(pprint.pformat(template_values))
    return render_to_response('%s/configuration_options.html' % instrument_name_lowercase,
                              template_values, context_instance=RequestContext(request))
Example #14
0
def reduction_options(request, reduction_id=None, instrument_name=None):
    """
        Display the reduction options form:
        
        If reduction_id exists, it will populate the form with information from that reduction.
            
        @param request: request object
        @param reduction_id: pk of reduction process object
    """
    
    logger.debug("Reduction: %s instrument_name=%s"%(inspect.stack()[0][3],instrument_name))
    
    instrument_name_capitals = str.capitalize(str(instrument_name))
    instrument_name_lowercase = str.lower(str(instrument_name))
    instrument_forms = view_util.import_module_from_app(instrument_name_lowercase,'forms')
    
    template_values = {}
    # Get reduction and configuration information
    config_obj = None
    if reduction_id is not None:
        reduction_proc = get_object_or_404(ReductionProcess, pk=reduction_id, owner=request.user)
        config_obj = reduction_proc.get_config()
    
    if request.method == 'POST':
        #logger.debug(pprint.pformat(request.POST.items()))
        
        options_form = instrument_forms.ReductionOptions(request.POST)
        # If the form is valid update or create an entry for it (if the data_file is different, a new entry is created!)
        if options_form.is_valid():
            new_reduction_id = options_form.to_db(request.user, reduction_id)
            if new_reduction_id is not None:
                messages.add_message(request, messages.SUCCESS, "Reduction parameters were sucessfully updated: " +
                "old_reduction_id=%s :: new_reduction_id=%s"%(reduction_id,new_reduction_id) )
                ## Keep the new reduction attached to the same configuration of the old one!
                # This is used for SEQ.
                # TODO: Check if SANS guys want that!
                if config_obj is not None:
                    reduction_proc = get_object_or_404(ReductionProcess, pk=new_reduction_id, owner=request.user)
                    config_obj.reductions.add(reduction_proc)
                    config_obj.save()
                return redirect(reverse('reduction_options',
                                        kwargs={'reduction_id' : new_reduction_id, 'instrument_name' : instrument_name}))
        else:
            messages.add_message(request, messages.ERROR, "The form is not valid. See errors above.")
    else:
        if reduction_id is not None:
            initial_values = instrument_forms.ReductionOptions.data_from_db(request.user, reduction_id)
        else:
            initial_values = copy.deepcopy(request.GET)
            if 'expt_name' in request.GET:
                initial_values['experiment'] = request.GET['expt_name']
        options_form = instrument_forms.ReductionOptions(initial=initial_values)
    
    breadcrumbs = Breadcrumbs()
    breadcrumbs.append_reduction(instrument_name_lowercase)
    
    if config_obj is not None:
        breadcrumbs.append_configuration(instrument_name_lowercase,config_obj.id)
        template_values.update({"properties":config_obj.get_data_dict()});
    if reduction_id is not None:
        breadcrumbs.append("reduction %s" % reduction_id)
    else:
        breadcrumbs.append("new reduction")

    # ICAT info url
    icat_url = reverse('catalog_run_info', args=[instrument_name_capitals, '0000'])
    icat_url = icat_url.replace('/0000', '')
    # TODO: add New an Save-As functionality
    template_values.update({'options_form': options_form,
                       'title': '%s Reduction' % instrument_name_capitals,
                       'breadcrumbs': breadcrumbs,
                       'reduction_id': reduction_id,
                       'icat_url': icat_url,
                       'instrument' : instrument_name_lowercase, })
    # Get existing jobs for this reduction
    if reduction_id is not None:
        existing_jobs = RemoteJob.objects.filter(reduction=reduction_proc)
        if len(existing_jobs) > 0:
            template_values['existing_jobs'] = existing_jobs.order_by('id')
        template_values['expt_list'] = reduction_proc.experiments.all()

    template_values = reduction_server.view_util.fill_template_values(request, **template_values)
    logger.debug(pprint.pformat(template_values))
    return render_to_response('%s/reduction_options.html' % instrument_name_lowercase,
                              template_values,context_instance=RequestContext(request))