def PhiRanges(phis, plot=True):
    """
        Given a list of phi ranges [a, b, c, d] it reduces in the phi ranges a-b and c-d
        @param phis: the list of phi ranges
        @param plot: set this to true to plot the result (must be run in Mantid), default is true
    """ 

    _printMessage('PhiRanges( %s,plot=%s)'%(str(phis),plot))

    #todo covert their string into Python array 
    
    if len(phis)/2 != float(len(phis))/2.:
        raise RuntimeError('Phi ranges must be given as pairs')

    try:
        #run the reductions, calculated will be an array with the names of all the workspaces produced
        calculated = []
        for i in range(0, len(phis), 2):
            SetPhiLimit(phis[i],phis[i+1])
            #reducedResult = ReductionSingleton()._reduce()
            #RenameWorkspace(reducedResult,'bob')
            #calculated.append(reducedResult)
            calculated.append(ReductionSingleton()._reduce())
            ReductionSingleton.replace(ReductionSingleton().settings())
    finally:
        _refresh_singleton()
    
    if plot:
        mantidplot.plotSpectrum(calculated, 0)
    
    #return just the workspace name of the full range
    return calculated[0]
def _WavRangeReduction(name_suffix=None):
    """
        Run a reduction that has been set up, from loading the raw data to calculating Q
    """

    try:
        # do a reduction
        calculated = [ReductionSingleton()._reduce()]

        periods = ReductionSingleton().get_sample().loader.entries    
        if len(periods) > 1:
            run_setup = ReductionSingleton().settings()
            for i in periods[1:len(periods)]:
                ReductionSingleton.replace(copy.deepcopy(run_setup))
                temp_workspaces = _setUpPeriod(i)
                # do a reduction for period i
                calculated.append(ReductionSingleton()._reduce())
                delete_workspaces(temp_workspaces)
            result = ReductionSingleton().get_out_ws_name(show_period=False)
            all_results = calculated[0]
            for name in calculated[1:len(calculated)]:
                all_results += ',' + name
            GroupWorkspaces(OutputWorkspace=result, InputWorkspaces=all_results)
        else:
            result = calculated[0]            
    finally:
        f=1 #_refresh_singleton()

    if name_suffix:
        old = result
        result += name_suffix
        RenameWorkspace(old, result)
        
    return result
Exemple #3
0
def WavRangeReduction(wav_start=None, wav_end=None, full_trans_wav=None, name_suffix=None):
    """
        Run a reduction that has been set up, from loading the raw data to calculating Q,  and
        reset the old setup
        @param wav_start: the first wavelength to be in the output data
        @param wav_end: the last wavelength in the output data
        @param full_trans_wav: if to use a wide wavelength range, the instrument's default wavelength range, for the transmission correction, false by default
    """
    _printMessage('WavRangeReduction(' + str(wav_start) + ', ' + str(wav_end) + ', '+str(full_trans_wav)+')')

    if not full_trans_wav is None:
        ReductionSingleton().full_trans_wav = full_trans_wav

    ReductionSingleton().to_wavelen.set_range(wav_start, wav_end)
    _printMessage('Running reduction for ' + str(ReductionSingleton().to_wavelen))

    try:
        # do a reduction
        calculated = [ReductionSingleton()._reduce()]

        periods = ReductionSingleton().get_sample().loader.entries    
        if len(periods) > 1:
            run_setup = ReductionSingleton().settings()
            for i in periods[1:len(periods)]:
                ReductionSingleton.replace(copy.deepcopy(run_setup))
                temp_workspaces = _setUpPeriod(i)
                # do a reduction for period i
                calculated.append(ReductionSingleton()._reduce())
                delete_workspaces(temp_workspaces)
            result = ReductionSingleton().get_out_ws_name(show_period=False)
            all_results = calculated[0]
            for name in calculated[1:len(calculated)]:
                all_results += ',' + name
            GroupWorkspaces(OutputWorkspace=result, InputWorkspaces=all_results)
        else:
            result = calculated[0] 
               
    finally:
        _refresh_singleton()

    if name_suffix:
        old = result
        result += name_suffix
        RenameWorkspace(old, result)
        
    return result
Exemple #4
0
def CompWavRanges(wavelens, plot=True):
    """
        Compares the momentum transfer results calculated from different wavelength ranges. Given
        the list of wave ranges [a, b, c] it reduces for wavelengths a-b, b-c and a-c.
        @param wavelens: the list of wavelength ranges
        @param plot: set this to true to plot the result (must be run in Mantid), default is true
    """ 

    _printMessage('CompWavRanges( %s,plot=%s)'%(str(wavelens),plot))

    #this only makes sense for 1D reductions
    if ReductionSingleton().to_Q.output_type == '2D':
        issueWarning('This wave ranges check is a 1D analysis, ignoring 2D setting')
        _printMessage('Set1D()')
        ReductionSingleton().to_Q.output_type = '1D'
    
    if type(wavelens) != type([]) or len(wavelens) < 2:
        if type(wavelens) != type((1,)):
            raise RuntimeError('Error CompWavRanges() requires a list of wavelengths between which reductions will be performed.')
    
    try:
        ReductionSingleton().to_wavelen.set_rebin(w_low=wavelens[0],
            w_high=wavelens[len(wavelens)-1])
        #run the reductions, calculated will be an array with the names of all the workspaces produced
        calculated = [ReductionSingleton()._reduce()]
        for i in range(0, len(wavelens)-1):
            ReductionSingleton.replace(ReductionSingleton().settings())
            ReductionSingleton().to_wavelen.set_rebin(
                            w_low=wavelens[i], w_high=wavelens[i+1])
            calculated.append(ReductionSingleton()._reduce())
    finally:
        _refresh_singleton()

    if plot:
        mantidplot.plotSpectrum(calculated, 0)
    
    #return just the workspace name of the full range
    return calculated[0]
def WavRangeReduction(wav_start=None, wav_end=None, full_trans_wav=None, name_suffix=None, combineDet=None, resetSetup=True, out_fit_settings = dict()):
    """
        Run reduction from loading the raw data to calculating Q. Its optional arguments allows specifics 
        details to be adjusted, and optionally the old setup is reset at the end. Note if FIT of RESCALE or SHIFT 
        is selected then both REAR and FRONT detectors are both reduced EXCEPT if only the REAR detector is selected
        to be reduced
        
        @param wav_start: the first wavelength to be in the output data
        @param wav_end: the last wavelength in the output data
        @param full_trans_wav: if to use a wide wavelength range, the instrument's default wavelength range, for the transmission correction, false by default
        @param name_suffix: append the created output workspace with this
        @param combineDet: combineDet can be one of the following:
                           'rear'                (run one reduction for the 'rear' detector data)
                           'front'               (run one reduction for the 'front' detector data, and rescale+shift 'front' data)
                           'both'                (run both the above two reductions)                  
                           'merged'              (run the same reductions as 'both' and additionally create a merged data workspace)                          
                            None                 (run one reduction for whatever detector has been set as the current detector 
                                                  before running this method. If front apply rescale+shift) 
        @param resetSetup: if true reset setup at the end
        @param out_fit_settings: An output parameter. It is used, specially when resetSetup is True, in order to remember the 'scale and fit' of the fitting algorithm. 
        @return Name of one of the workspaces created
    """
    _printMessage('WavRangeReduction(' + str(wav_start) + ', ' + str(wav_end) + ', '+str(full_trans_wav)+')')
    # these flags indicate if it is necessary to reduce the front bank, the rear bank and if it is supposed to merge them
    reduce_rear_flag = False
    reduce_front_flag = False
    merge_flag = False
    
    # combineDet from None to 'rear' or 'front'
    if combineDet is None:
        if ReductionSingleton().instrument.cur_detector().isAlias('FRONT'):
            combineDet = 'front'
        else:
            combineDet = 'rear'
    
    if not full_trans_wav is None:
        ReductionSingleton().full_trans_wav = full_trans_wav

    ReductionSingleton().to_wavelen.set_range(wav_start, wav_end)

    rAnds = ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift
    # check if fit is required.
    fitRequired = False 
    if rAnds.fitScale or rAnds.fitShift:
        fitRequired = True

    com_det_option = combineDet.lower()
    
    # the only special case where reduce rear is not required is
    # if the user chose to reduce front and does not require fit 
    if not (com_det_option == 'front' and not fitRequired):
        reduce_rear_flag = True
    if (com_det_option != 'rear'):
        reduce_front_flag = True
    if (com_det_option == 'merged'):
        merge_flag = True
    
    #The shift and scale is always on the front detector.
    if not reduce_front_flag:
        fitRequired = False

    #To backup value of singleton which are temporarily modified in this method
    toRestoreAfterAnalysis = ReductionSingleton().instrument.cur_detector().name()
    toRestoreOutputParts = ReductionSingleton().to_Q.outputParts

    # if 'merged' then when cross section is calculated output the two individual parts
    # of the cross section. These additional outputs are required to calculate
    # the merged workspace
    if merge_flag:           
        ReductionSingleton().to_Q.outputParts = True

    # do reduce rear bank data
    if reduce_rear_flag:
        ReductionSingleton().instrument.setDetector('rear')
        retWSname_rear = _WavRangeReduction(name_suffix)
        retWSname = retWSname_rear
    
    # do reduce front bank
    if reduce_front_flag:
        # it is necessary to replace the Singleton if a reduction was done before
        if (reduce_rear_flag):
            # In this case, it is necessary to reload the files, in order to move the components to the
            # correct position defined by its get_beam_center. (ticket #5942)

            # first copy the settings
            ReductionSingleton.replace(ReductionSingleton().settings())

            # for the LOQ instrument, if the beam centers are different, we have to reload the data.
            if (ReductionSingleton().instrument._NAME == 'LOQ' and 
               (ReductionSingleton().get_beam_center('rear') != ReductionSingleton().get_beam_center('front'))):
                
                # It is necessary to reload sample, transmission and can files.
                #reload sample
                issueWarning('Trying to reload workspaces')
                ReductionSingleton().instrument.setDetector('front')
                ReductionSingleton()._sample_run.reload(ReductionSingleton())
                #reassign can
                if ReductionSingleton().background_subtracter:
                    ReductionSingleton().background_subtracter.assign_can(ReductionSingleton())
                if ReductionSingleton().samp_trans_load:
                    #refresh Transmission
                    ReductionSingleton().samp_trans_load.execute(ReductionSingleton(), None)
                if ReductionSingleton().can_trans_load:
                    ReductionSingleton().can_trans_load.execute(ReductionSingleton(),None)
                        
        ReductionSingleton().instrument.setDetector('front')

        retWSname_front = _WavRangeReduction(name_suffix)
        retWSname = retWSname_front

    # do fit and scale if required
    if fitRequired:
        scale, shift = _fitRescaleAndShift(rAnds, retWSname_front, retWSname_rear)
        ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.shift = shift
        ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.scale = scale
        if scale < 0:
            issueWarning("Fit returned SCALE negative")
    
    shift = ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.shift
    scale = ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.scale

    # apply the merge algorithm
    if merge_flag:
        retWSname_merged = retWSname_rear
        if retWSname_merged.count('rear') == 1:
          retWSname_merged = retWSname_merged.replace('rear', 'merged')
        else:
          retWSname_merged = retWSname_merged + "_merged"

        Nf = mtd[retWSname_front+"_sumOfNormFactors"]
        Nr = mtd[retWSname_rear+"_sumOfNormFactors"]
        Cf = mtd[retWSname_front+"_sumOfCounts"]
        Cr = mtd[retWSname_rear+"_sumOfCounts"]
        consider_can = True
        try:
            Nf_can = mtd[retWSname_front+"_can_tmp_sumOfNormFactors"]
            Nr_can = mtd[retWSname_rear+"_can_tmp_sumOfNormFactors"]
            Cf_can = mtd[retWSname_front+"_can_tmp_sumOfCounts"]
            Cr_can = mtd[retWSname_rear+"_can_tmp_sumOfCounts"]
            if Cr_can is None:
                consider_can = False
        except KeyError :
            #The CAN was not specified
            consider_can = False
            
            
        fisF = mtd[retWSname_front]
        fisR = mtd[retWSname_rear]
            
        minQ = min(min(fisF.dataX(0)), min(fisR.dataX(0)))
        maxQ = max(max(fisF.dataX(0)), max(fisR.dataX(0)))

        if maxQ > minQ:
            #preparing the sample
            CropWorkspace(InputWorkspace=Nf, OutputWorkspace=Nf, XMin=minQ, XMax=maxQ)
            CropWorkspace(InputWorkspace=Nr, OutputWorkspace=Nr, XMin=minQ, XMax=maxQ)
            CropWorkspace(InputWorkspace=Cf, OutputWorkspace=Cf, XMin=minQ, XMax=maxQ)
            CropWorkspace(InputWorkspace=Cr, OutputWorkspace=Cr, XMin=minQ, XMax=maxQ)
            if consider_can:
                #preparing the can
                CropWorkspace(InputWorkspace=Nf_can, OutputWorkspace=Nf_can, XMin=minQ, XMax=maxQ)
                CropWorkspace(InputWorkspace=Nr_can, OutputWorkspace=Nr_can, XMin=minQ, XMax=maxQ)
                CropWorkspace(InputWorkspace=Cf_can, OutputWorkspace=Cf_can, XMin=minQ, XMax=maxQ)
                CropWorkspace(InputWorkspace=Cr_can, OutputWorkspace=Cr_can, XMin=minQ, XMax=maxQ)
            
            mergedQ = (Cf+shift*Nf+Cr)/(Nf/scale + Nr)        
            if consider_can:
                mergedQ -= (Cf_can+Cr_can)/(Nf_can/scale + Nr_can)
            
            RenameWorkspace(mergedQ, retWSname_merged)
        else:
            issueWarning('rear and front data has no overlapping q-region. Merged workspace no calculated')
        
        delete_workspaces(retWSname_rear+"_sumOfCounts")
        delete_workspaces(retWSname_rear+"_sumOfNormFactors")
        delete_workspaces(retWSname_front+"_sumOfCounts")
        delete_workspaces(retWSname_front+"_sumOfNormFactors")
        if consider_can:
            delete_workspaces(retWSname_front+"_can_tmp_sumOfNormFactors")
            delete_workspaces(retWSname_rear+"_can_tmp_sumOfNormFactors")
            delete_workspaces(retWSname_front+"_can_tmp_sumOfCounts")
            delete_workspaces(retWSname_rear+"_can_tmp_sumOfCounts")

        retWSname = retWSname_merged

    #applying scale and shift on the front detector reduced data
    if reduce_front_flag:
        frontWS = mtd[retWSname_front]
        frontWS = (frontWS+shift)*scale
        RenameWorkspace(frontWS, retWSname_front)

    # finished calculating cross section so can restore these value
    ReductionSingleton().to_Q.outputParts = toRestoreOutputParts
    ReductionSingleton().instrument.setDetector(toRestoreAfterAnalysis)
    
    # update the scale and shift values of out_fit_settings
    out_fit_settings['scale'] = ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.scale
    out_fit_settings['shift'] = ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.shift

    if resetSetup:
        _refresh_singleton()
    
    return retWSname