Пример #1
0
    def do_white(self, white_run, spectra_masks, map_file): 
        """
        Normalise to a specified white-beam run
        """
        whitews_name = common.create_resultname(white_run, suffix='-white')
        if mtd.workspaceExists(whitews_name):
            return mtd[whitews_name]

        # Load
        white_data = self.load_data(white_run)
        # Normalise
        white_ws = self.normalise(white_data, whitews_name, self.normalise_method)
        # Units conversion
        ConvertUnits(white_ws, white_ws, "Energy", AlignBins=0)
        # This both integrates the workspace into one bin spectra and sets up common bin boundaries for all spectra
        low = self.wb_integr_range[0]
        upp = self.wb_integr_range[1]
        if low > upp:
            raise ValueError("White beam integration range is inconsistent. low=%d, upp=%d" % (low,upp))
        delta = 2.0*(upp - low)
        Rebin(white_ws, white_ws, [low, delta, upp])
        # Why aren't we doing this...
        #Integration(white_ws, white_ws, RangeLower=low, RangeUpper=upp)

        # Masking and grouping
        white_ws = self.remap(white_ws, spectra_masks, map_file)

        # White beam scale factor
        white_ws *= self.wb_scale_factor

        return white_ws
Пример #2
0
    def convert_to_energy(self, mono_run, ei, white_run=None, mono_van=None,\
                          abs_ei=None, abs_white_run=None, save_path=None, Tzero=None, \
                          motor=None, offset=None):
        """
        One-shot function to convert the given runs to energy
        """
        # Check if we need to perform the absolute normalisation first
        if not mono_van is None:
            if abs_ei is None:
                abs_ei = ei
            mapping_file = self.abs_map_file
            spectrum_masks = self.spectra_masks 
            monovan_wkspace = self.mono_van(mono_van, abs_ei, abs_white_run, mapping_file, spectrum_masks)
            
            # TODO: Need a better check than this...
            if (abs_white_run is None):
                self.log("Performing Normalisation to Mono Vanadium.")
                norm_factor = self.calc_average(monovan_wkspace)
            else:
                self.log("Performing Absolute Units Normalisation.")
                # Perform Abs Units...
                norm_factor = self.monovan_abs(monovan_wkspace)
            mtd.deleteWorkspace(monovan_wkspace.getName())
        else:
            norm_factor = None

        # Figure out what to call the workspace 
        result_name = mono_run
        if not result_name is None:
            result_name = common.create_resultname(mono_run)
        
        # Main run file conversion
        sample_wkspace = self.mono_sample(mono_run, ei, white_run, self.map_file,
                                          self.spectra_masks, result_name, Tzero)
        if not norm_factor is None:
            sample_wkspace /= norm_factor

        
        #calculate psi from sample environment motor and offset 
        if (offset is None):
            self.motor_offset = 0
        else:
            self.motor_offset = float(offset)
        
        self.motor=0
        if not (motor is None):
        # Check if motor name exists    
            if sample_wkspace.getRun().hasProperty(motor):
                self.motor=sample_wkspace.getRun()[motor].value[0]
                self.log("Motor value is %s" % self.motor)
            else:
                self.log("Could not find such sample environment log. Will use psi=offset")
        self.psi = self.motor+self.motor_offset
        # Save then finish
        self.save_results(sample_wkspace, save_path)
        # Clear loaded raw data to free up memory
        common.clear_loaded_data()
        
        return sample_wkspace
Пример #3
0
    def mono_sample(self, mono_run, ei_guess, white_run=None, map_file=None,
                    spectra_masks=None, result_name=None, Tzero=None):
        """Convert a mono-chromatic sample run to DeltaE.
        If multiple run files are passed to this function, they are summed into a run and then processed
        """
        # Load data
        sample_data = self.load_data(mono_run)
        # Create the result name if necessary
        if result_name is None:
            result_name = common.create_resultname(mono_run, prefix=self.instr_name)

        return self._do_mono(sample_data, sample_data, result_name, ei_guess, 
                                  white_run, map_file, spectra_masks, Tzero)
Пример #4
0
    def mono_van(self, mono_van, ei_guess, white_run=None, map_file=None,
                 spectra_masks=None, result_name=None, Tzero=None):
        """Convert a mono vanadium run to DeltaE.
        If multiple run files are passed to this function, they are summed into a run and then processed         
        """
        # Load data
        sample_data = self.load_data(mono_van)
        # Create the result name if necessary
        if result_name is None:
            result_name = common.create_resultname(mono_van)

        monovan = self._do_mono(sample_data, sample_data, result_name, ei_guess, 
                                white_run, map_file, spectra_masks, Tzero)
        # Normalize by vanadium sample weight
        monovan /= float(self.van_mass)/float(self.van_rmm)
        return monovan
Пример #5
0
def apply_absolute_normalization(Reducer,deltaE_wkspace_sample,monovan_run,ei_guess,wb_mono):
    """  Function applies absolute normalization factor to the target workspace
         and calculates this factor if necessary

         Inputs:
         Reducer           --    properly initialized class which performs reduction
         deltaE_wkspace_sample-- the workspace which should be modified
         monovan_run          -- run number for monochromatic vanadium sample at current energy
         ei_guess             -- estimated neutrons incident energy
         wb_mono              -- white bean vanadium run number.
    """
    if Reducer.mono_correction_factor != None :
         absnorm_factor=float(Reducer.mono_correction_factor)
         Reducer.log('##### Using supplied workspace correction factor                          ######')
         Reducer.log('      Value : '+str(absnorm_factor))

    else:
        Reducer.log('##### Evaluate the integral from the monovan run and calculate the correction factor ######')
        Reducer.log('      Using absolute units vanadium integration range : '+str(Reducer.monovan_integr_range))
        #
        result_ws_name = common.create_resultname(monovan_run)
        # check the case when the sample is monovan itself (for testing purposes)
        if result_ws_name == deltaE_wkspace_sample.name() :
            deltaE_wkspace_monovan = CloneWorkspace(InputWorkspace=deltaE_wkspace_sample,OutputWorkspace=result_ws_name+'-monovan');
            deltaE_wkspace_monovan=Reducer.remap(deltaE_wkspace_monovan,None,Reducer.monovan_mapfile)
        else:
            # convert to monovan to energy
            map_file            = Reducer.map_file;
            Reducer.map_file    = Reducer.monovan_mapfile;
            deltaE_wkspace_monovan = Reducer.convert_to_energy(monovan_run, ei_guess, wb_mono)
            Reducer.map_file = map_file

        ei_monovan = deltaE_wkspace_monovan.getRun().getLogData("Ei").value
        Reducer.log('      Incident energy found for monovanadium run: '+str(ei_monovan)+' meV')


        (absnorm_factorL,absnorm_factorSS,absnorm_factorP,absnorm_factTGP) = get_abs_normalization_factor(Reducer,deltaE_wkspace_monovan.getName(),ei_monovan)

        Reducer.log('Absolute correction factor S^2: {0:10.4f} Libisis: {1:10.4f} Puasonian: {2:10.4f}  TGP: {3:10.4f} '.format(absnorm_factorSS,absnorm_factorL,absnorm_factorP,absnorm_factTGP))
        absnorm_factor = absnorm_factTGP;


    deltaE_wkspace_sample = deltaE_wkspace_sample/absnorm_factor;


    return deltaE_wkspace_sample
Пример #6
0
def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=None,**kwargs):
    """ One step conversion of run into workspace containing information about energy transfer
    Usage:
    >>arb_units(wb_run,sample_run,ei_guess,rebin)

    >>arb_units(wb_run,sample_run,ei_guess,rebin,**arguments)

    >>arb_units(wb_run,sample_run,ei_guess,rebin,mapfile,**arguments)

    >>arb_units(wb_run   Whitebeam run number or file name or workspace
                sample_run  sample run number or file name or workspace
                ei_guess    Ei guess
                rebin       Rebin parameters
                mapfile     Mapfile -- if absent/'default' the defaults from IDF are used
                monovan_run If present will do the absolute units normalization. Number of additional parameters
                            specified in **kwargs is usually requested for this. If they are absent, program uses defaults,
                            but the defaults (e.g. sample_mass or sample_rmm ) are usually incorrect for a particular run.
                arguments   The dictionary containing additional keyword arguments.
                            The list of allowed additional arguments is defined in InstrName_Parameters.xml file, located in
                            MantidPlot->View->Preferences->Mantid->Directories->Parameter Definitions

    with run numbers as input:
    >>dgreduce.arb_units(1000,10001,80,[-10,.1,70])  # will run on default instrument

    >>dgreduce.arb_units(1000,10001,80,[-10,.1,70],'mari_res', additional keywords as required)

    >>dgreduce.arb_units(1000,10001,80,'-10,.1,70','mari_res',fixei=True)

    A detector calibration file must be specified if running the reduction with workspaces as input
    namely:
    >>w2=iliad("wb_wksp","run_wksp",ei,rebin_params,mapfile,det_cal_file=cal_file
               ,diag_remove_zero=False,norm_method='current')


    type help() for the list of all available keywords. All availible keywords are provided in InstName_Parameters.xml file


    Some samples are:
    norm_method =[monitor-1],[monitor-2][Current]
    background  =False , True
    fixei       =False , True
    save_format =['.spe'],['.nxspe'],'none'
    detector_van_range          =[20,40] in mev

    bkgd_range  =[15000,19000]  :integration range for background tests

    second_white     - If provided an additional set of tests is performed on this. (default = None)
    hardmaskPlus     - A file specifying those spectra that should be masked without testing (default=None)
    tiny             - Minimum threshold for acceptance (default = 1e-10)
    large            - Maximum threshold for acceptance (default = 1e10)
    bkgd_range       - A list of two numbers indicating the background range (default=instrument defaults)
    diag_van_median_rate_limit_lo      - Lower bound defining outliers as fraction of median value (default = 0.01)
    diag_van_median_rate_limit_hi      - Upper bound defining outliers as fraction of median value (default = 100.)
    diag_van_median_sigma_lo           - Fraction of median to consider counting low for the white beam diag (default = 0.1)
    diag_van_median_sigma_hi           - Fraction of median to consider counting high for the white beam diag (default = 1.5)
    diag_van_sig  - Error criterion as a multiple of error bar i.e. to fail the test, the magnitude of the
                    difference with respect to the median value must also exceed this number of error bars (default=0.0)
    diag_remove_zero                - If true then zeroes in the vanadium data will count as failed (default = True)
    diag_samp_samp_median_sigma_lo  - Fraction of median to consider counting low for the white beam diag (default = 0)
    diag_samp_samp_median_sigma_hi  - Fraction of median to consider counting high for the white beam diag (default = 2.0)
    diag_samp_sig                   - Error criterion as a multiple of error bar i.e. to fail the test, the magnitude of the"
                                      difference with respect to the median value must also exceed this number of error bars (default=3.3)
    variation       -The number of medians the ratio of the first/second white beam can deviate from
                     the average by (default=1.1)
    bleed_test      - If true then the CreatePSDBleedMask algorithm is run
    bleed_maxrate   - If the bleed test is on then this is the maximum framerate allowed in a tube
    bleed_pixels    - If the bleed test is on then this is the number of pixels ignored within the
                       bleed test diagnostic
    print_results - If True then the results are printed to the screen

    diag_remove_zero =True, False (default):Diag zero counts in background range
    bleed=True , turn bleed correction on and off on by default for Merlin and LET

    sum =True,False(default) , sum multiple files

    det_cal_file= a valid detector block file and path or a raw file. Setting this
                  will use the detector calibraion from the specified file NOT the
                  input raw file
    mask_run = RunNumber to use for diag instead of the input run number

    one2one =True, False :Reduction will not use a mapping file

    hardmaskPlus=Filename :load a hardmarkfile and apply together with diag mask

    hardmaskOnly=Filename :load a hardmask and use as only mask

    """
    global Reducer
    if Reducer is None or Reducer.instrument is None:
        raise ValueError("instrument has not been defined, call setup(instrument_name) first.")
# --------------------------------------------------------------------------------------------------------
#    Deal with mandatory parameters for this and may be some top level procedures
# --------------------------------------------------------------------------------------------------------
    Reducer.log("****************************************************************");
    if isinstance(sample_run,api.Workspace) or (isinstance(sample_run,str) and sample_run in mtd):
        Reducer.log('*** DGreduce run for: {0:>20} :  Workspace name: {1:<20} '.format(Reducer.instr_name,str(sample_run)))
    else:
        Reducer.log('*** DGreduce run for: {0:>20} :  Run number/s : {1:<20} '.format(Reducer.instr_name,str(sample_run)))

    try:
        n,r=funcreturns.lhs_info('both')
        wksp_out=r[0]
    except:
        if sample_run == 0:
            #deal with the current run being parsed as 0 rather than 00000
            sample_run='00000'
        wksp_out=Reducer.instr_name+str(sample_run)+'.spe'
        if kwargs.has_key('sum') and kwargs.get('sum')==True:
            wksp_out=inst_name+str(sample_run[0])+'sum'+'.spe'

    start_time=time.time()

    if sample_run=='00000' and mtd.doesExist(inst_name+'00000.raw')==True:
        Reducer.log('Deleting previous instance of temp data')
        DeleteWorkspace(Workspace=inst_name+'00000.raw')


    # we may want to run absolute units normalization and this function has been called with monovan run or helper procedure
    abs_units_defaults_check = False
    if monovan_run != None :
       # check if mono-vanadium is provided as multiple files list or just put in brackets occasionally
        Reducer.log("****************************************************************");
        Reducer.log('*** Output will be in absolute units of mb/str/mev/fu')
        if isinstance(monovan_run,list):
                if len(monovan_run)>1:
                    raise IOError(' Can currently work only with single monovan file but list supplied')
                else:
                    monovan_run = monovan_run[0];
        abs_units_defaults_check =True
        if '_defaults_have_changed' in kwargs:
            del kwargs['_defaults_have_changed']
            abs_units_defaults_check =False
    if "wb_for_monovanadium" in kwargs :
         wb_for_monovanadium = kwargs['wb_for_monovanadium']
         del kwargs['wb_for_monovanadium']
    else:
         wb_for_monovanadium = wb_run;



    if isinstance(ei_guess,str):
        ei_guess = float(ei_guess)

    # set rebinning range
    Reducer.energy_bins = rebin
    Reducer.incident_energy = ei_guess;
    if Reducer.energy_bins[2] > ei_guess:
        Reducer.log('Error: rebin max rebin range {0:f} exceeds incident energy {1:f}'.format(Reducer.energy_bins[2],ei_guess),'Error')
        return

    # Process old legacy parameters which are easy to re-define in dgreduce rather then transfer through Mantid
    program_args = process_legacy_parameters(**kwargs)

    # set non-default reducers parameters and check if all optional keys provided as parameters are acceptable and have been defined in IDF
    changed_Keys=Reducer.set_input_parameters(**program_args);

    # inform user about changed parameters

    Reducer.log("*** Provisional Incident energy: {0:>12.3f} mEv".format(ei_guess))
    Reducer.log("****************************************************************");
    for key in changed_Keys:
        val = getattr(Reducer,key);
        Reducer.log("  Value of : {0:<25} is set to : {1:<20} ".format(key,val))


    save_dir = config.getString('defaultsave.directory')
    Reducer.log("****************************************************************");
    if monovan_run != None and not('van_mass' in changed_Keys or 'vanadium-mass' in changed_Keys) :
         Reducer.log("*** Monochromatic vanadium mass used : {0} ".format(Reducer.van_mass))
    Reducer.log("*** By default results are saved into: {0}".format(save_dir));
    Reducer.log("****************************************************************");
    #do we run absolute units normalization and need to warn users if the parameters needed for that have not changed from defaults
    if abs_units_defaults_check :
        Reducer.check_abs_norm_defaults_changed(changed_Keys);

    #process complex parameters


    # map file given in parameters overrides default map file
    if map_file != 'default' :
        Reducer.map_file = map_file
    # defaults can be None too, but can be a file
    if  Reducer.map_file == None:
        Reducer.log('one2one map selected')


    if  Reducer.det_cal_file != None :
        if isinstance(Reducer.det_cal_file,str) and not Reducer.det_cal_file in mtd : # it is a file
            Reducer.log('Setting detector calibration file to '+Reducer.det_cal_file)
        else:
           Reducer.log('Setting detector calibration to {0}, which is probably a workspace '.format(str(Reducer.det_cal_file)))
    else:
        Reducer.log('Setting detector calibration to detector block info from '+str(sample_run))

    # check if reducer can find all non-run files necessary for the reduction before starting long run.
    Reducer.check_necessary_files(monovan_run);

    print 'Output will be normalized to', Reducer.normalise_method
    if (numpy.size(sample_run)) > 1 and Reducer.sum_runs:
        #this sums the runs together before passing the summed file to the rest of the reduction
        #this circumvents the inbuilt method of summing which fails to sum the files for diag

        #the D.E.C. tries to be too clever so we have to fool it into thinking the raw file is already exists as a workpsace
        sumfilename=Reducer.instr_name+str(sample_run[0])+'.raw'
        sample_run =sum_files(Reducer.instr_name,sumfilename, sample_run)
        common.apply_calibration(Reducer.instr_name,sample_run,Reducer.det_cal_file)

        #sample_run = RenameWorkspace(InputWorkspace=accum,OutputWorkspace=inst_name+str(sample_run[0])+'.raw')


    if Reducer.mask_run == None :
        mask_run=sample_run

    masking = None;
    masks_done=False
    if not Reducer.run_diagnostics:
       header="Diagnostics including hard masking is skipped "
       masks_done = True;
    if Reducer.save_and_reuse_masks :
        raise NotImplementedError("Save and reuse masks option is not yet implemented")
        mask_file_name = common.create_resultname(str(mask_run),Reducer.instr_name,'_masks.xml')
        mask_full_file = FileFinder.getFullPath(mask_file_name)
        if len(mask_full_file) > 0 :
            masking = LoadMask(Instrument=Reducer.instr_name,InputFile=mask_full_file,OutputWorkspace=mask_file_name)
            #Reducer.hard_mask_file = mask_full_file;
            #Reducer.use_hard_mask_only = True
            masks_done=True
            header="Masking fully skipped and processed {0} spectra and  {1} bad spectra "
        else:
            pass
#-------------------------------------------------------------------------------------------------------------------------------------------------------
#  Here we give control to the Reducer
# --------------------------------------------------------------------------------------------------------
     # diag the sample and detector vanadium. It will deal with hard mask only if it is set that way
    if not   masks_done:
        print '########### Run diagnose for sample run ##############################'
        masking = Reducer.diagnose(wb_run,sample = mask_run,
                                    second_white = None,print_results=True)
        header = "Diag Processed workspace with {0:d} spectra and masked {1:d} bad spectra"


   # Calculate absolute units:
        if monovan_run != None :
            if Reducer.mono_correction_factor == None :
                if Reducer.use_sam_msk_on_monovan == True:
                    Reducer.log('  Applying sample run mask to mono van')
                else:
                    if not Reducer.use_hard_mask_only : # in this case the masking2 is different but points to the same workspace Should be better soulution for that.
                        print '########### Run diagnose for monochromatic vanadium run ##############'
                        masking2 = Reducer.diagnose(wb_for_monovanadium,sample=monovan_run,
                                         second_white = None,rint_results=True)
                        masking +=  masking2
                        DeleteWorkspace(masking2)


            else: # if Reducer.mono_correction_factor != None :
                pass

    # save mask if it does not exist and has been already loaded
    if Reducer.save_and_reuse_masks and not masks_done:
        SaveMask(InputWorkspace=masking,OutputFile = mask_file_name,GroupedDetectors=True)

    # Very important statement propagating masks for further usage in convert_to_energy
    Reducer.spectra_masks=masking
    # estimate and report the number of failing detectors
    failed_sp_list,nSpectra = get_failed_spectra_list_from_masks(masking)
    nMaskedSpectra = len(failed_sp_list)
    # this tells turkey in case of hard mask only but everything else semens work fine
    print header.format(nSpectra,nMaskedSpectra)
     #Run the conversion first on the sample
    deltaE_wkspace_sample = Reducer.convert_to_energy(sample_run, ei_guess, wb_run)


    # calculate absolute units integral and apply it to the workspace
    if monovan_run != None or Reducer.mono_correction_factor != None :
        deltaE_wkspace_sample = apply_absolute_normalization(Reducer,deltaE_wkspace_sample,monovan_run,ei_guess,wb_run)
        # Hack for multirep
        #if isinstance(monovan_run,int):
        #    filename = common.find_file(monovan_run)
        #    output_name = common.create_dataname(filename);
       #     DeleteWorkspace(output_name);


    results_name = deltaE_wkspace_sample.name();
    if results_name != wksp_out:
       RenameWorkspace(InputWorkspace=results_name,OutputWorkspace=wksp_out)


    ei= (deltaE_wkspace_sample.getRun().getLogData("Ei").value)
    print 'Incident energy found for sample run: ',ei,' meV'

    end_time=time.time()
    print 'Elapsed time =',end_time-start_time, 's'

    if mtd.doesExist('_wksp.spe-white')==True:
        DeleteWorkspace(Workspace='_wksp.spe-white')
    # Hack for multirep mode?
    if mtd.doesExist('hard_mask_ws') == True:
        DeleteWorkspace(Workspace='hard_mask_ws')

    return deltaE_wkspace_sample