Esempio n. 1
0
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]
Esempio n. 2
0
def DisplayMask(mask_worksp=None):
    """
        Displays masking by applying it to a workspace and displaying
        it in instrument view. If no workspace is passed a copy of the
        sample workspace is used, unless no sample was loaded and then
        an empty instrument will be shown
        @param mask_worksp: optional this named workspace will be modified and should be from the currently selected instrument
        @return the name of the workspace that was displayed
    """
    #this will be copied from a sample work space if one exists
    counts_data = None
    instrument = ReductionSingleton().instrument
    
    if not mask_worksp:
        mask_worksp = '__CurrentMask'
        samp = LAST_SAMPLE 
        
        if samp:
            counts_data = '__DisplayMasked_tempory_wksp'
            Integration(samp, counts_data)
            CloneWorkspace(samp, mask_worksp)
        else:
            instrument.load_empty(mask_worksp)
            instrument.set_up_for_run('emptyInstrument')
        
    ReductionSingleton().mask.display(mask_worksp, ReductionSingleton(), counts_data)
    if counts_data:
        mantid.deleteWorkspace(counts_data)
        
    return mask_worksp
Esempio n. 3
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
Esempio n. 4
0
def LimitsR(rmin, rmax, quiet=False, reducer=None):
    if reducer == None:
        reducer = ReductionSingleton().reference()

    if not quiet:
        _printMessage('LimitsR(' + str(rmin) + ', ' +str(rmax) + ')', reducer)

    reducer.mask.set_radi(rmin, rmax)
    reducer.CENT_FIND_RMIN = float(rmin)/1000.
    reducer.CENT_FIND_RMAX = float(rmax)/1000.    
Esempio n. 5
0
def LimitsQXY(qmin, qmax, step, type):
    """
        To set the bin parameters for the algorithm Qxy()
        @param qmin: the first Q value to include
        @param qmaz: the last Q value to include
        @param step: bin width
        @param type: pass LOG for logarithmic binning
    """
    _printMessage('LimitsQXY(' + str(qmin) + ', ' + str(qmax) +', ' + str(step) + ', ' + str(type) + ')')
    settings = ReductionSingleton().user_settings
    if settings is None:
        raise RuntimeError('MaskFile() first')

    settings.readLimitValues('L/QXY ' + str(qmin) + ' ' + str(qmax) + ' ' + str(step) + '/'  + type, ReductionSingleton())
Esempio n. 6
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
Esempio n. 7
0
def SetDetectorOffsets(bank, x, y, z, rot, radius, side):
    """
        Adjust detector position away from position defined in IDF. On SANS2D the detector 
        banks can be moved around. This method allows fine adjustments of detector bank position 
        in the same way as the DET/CORR userfile command works. Hence please see
        http://www.mantidproject.org/SANS_User_File_Commands#DET for details.
        
        Note, for now, this command will only have an effect on runs loaded 
        after this command have been executed (because it is when runs are loaded 
        that components are moved away from the positions set in the IDF)
        
        @param bank: Must be either 'front' or 'rear' (not case sensitive)       
        @param x: shift in mm
        @param y: shift in mm
        @param z: shift in mm
        @param rot: shift in degrees
        @param radius: shift in mm
        @param side: shift in mm
    """  
    _printMessage("SetDetectorOffsets(" + str(bank) + ', ' + str(x) 
                  + ','+str(y) + ',' + str(z) + ',' + str(rot) 
                  + ',' + str(radius) + ',' + str(side) + ')')

    detector = ReductionSingleton().instrument.getDetector(bank)    
    detector.x_corr = x
    detector.y_corr = y
    detector.z_corr = z
    detector.rot_corr = rot
    detector.radius_corr = radius
    detector.side_corr = side   
Esempio n. 8
0
def LimitsQ(*args):
    settings = ReductionSingleton().user_settings
    if settings is None:
        raise RuntimeError('MaskFile() first')

    # If given one argument it must be a rebin string
    if len(args) == 1:
        val = args[0]
        if type(val) == str:
            _printMessage("LimitsQ(" + val + ")")
            settings.readLimitValues("L/Q " + val, ReductionSingleton())
        else:
            issueWarning("LimitsQ can only be called with a single string or 4 values")
    elif len(args) == 4:
        qmin,qmax,step,step_type = args
        _printMessage('LimitsQ(' + str(qmin) + ', ' + str(qmax) +', ' + str(step) + ','  + str(step_type) + ')')
        settings.readLimitValues('L/Q ' + str(qmin) + ' ' + str(qmax) + ' ' + str(step) + '/'  + step_type, ReductionSingleton())
    else:
        issueWarning("LimitsQ called with " + str(len(args)) + " arguments, 1 or 4 expected.")
Esempio n. 9
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]
Esempio n. 10
0
def SetFrontEfficiencyFile(filename):
    front_det = ReductionSingleton().instrument.getDetector('front')
    front_det.correction_file = filename
Esempio n. 11
0
def SetRearEfficiencyFile(filename):
    rear_det = ReductionSingleton().instrument.getDetector('rear')
    rear_det.correction_file = filename
Esempio n. 12
0
def _refresh_singleton():
    ReductionSingleton.clean(isis_reducer.ISISReducer)
    ReductionSingleton().remove_settings()
Esempio n. 13
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