Пример #1
0
 def load_data(self, runs):
     """
     Load a run or list of runs. If a list of runs is given then
     they are summed into one.
     """
     result_ws = common.load_runs(runs, sum=True)
     self.setup_mtd_instrument(result_ws)
     return result_ws
Пример #2
0
def _do_background_test(sample_run, white_counts, comp_white_counts, bkgd_range,
                        bkgd_threshold, remove_zero, signif, hard_mask_spectra):
    """
    Run the background tests on the integrated sample run normalised by an
    integrated white beam run

    Required inputs:
    
      sample_run          - The run number or filepath of the sample run
      white_counts        - A workspace containing the integrated counts from a
                            white beam vanadium run
      comp_white_counts - A second workspace containing the integrated counts from a
                            different white beam vanadium run
      bkgd_range          - The background range as a list of 2 numbers: [min,max]. 
                            If not present then they are taken from the parameter file.
      bkgd_threshold      - High threshold for background removal in multiples of median
      remove_zero         - If true then zeroes in the data will count as failed (default = False)
      signif              - Counts within this number of multiples of the 
                            standard dev will be kept (default = 3.3)
      prev_ma sks         - If present then this masking is applied to the sample run before the
                            test is applied. It is expected as a MaskWorkspace
    """
    mtd.sendLogMessage('Running background count test')
    # Load and integrate the sample using the defined background range. If none is given use the
    # instrument defaults
    data_ws = common.load_runs(sample_run)
    instrument = data_ws.getInstrument()
    if bkgd_range is None:
        min_value = float(instrument.getNumberParameter('bkgd-range-min')[0])
        max_value = float(instrument.getNumberParameter('bkgd-range-max')[0])
    elif len(bkgd_range) != 2:
        raise ValueError("The provided background range is incorrect. A list of 2 numbers is required.")
    else:
        min_value = bkgd_range[0]
        if min_value is None:
            float(instrument.getNumberParameter('bkgd-range-min')[0])
        max_value = bkgd_range[1]
        if max_value is None:
            float(instrument.getNumberParameter('bkgd-range-max')[0])

    # Get the total counts
    sample_counts = Integration(data_ws, '__counts_mono-sample', RangeLower=min_value, \
                                RangeUpper=max_value).workspace()

    # Apply hard mask spectra and previous masking first
    MaskDetectors(sample_counts, SpectraList=hard_mask_spectra, MaskedWorkspace=white_counts)
    
    # If we have another white beam then compute the harmonic mean of the counts
    # The harmonic mean: 1/av = (1/Iwbv1 + 1/Iwbv2)/2
    # We'll resuse the comp_white_counts workspace as we don't need it anymore
    white_count_mean = white_counts
    if comp_white_counts is not None:
        MaskDetectors(sample_counts, MaskedWorkspace=comp_white_counts)
        white_count_mean = (comp_white_counts * white_counts)/(comp_white_counts + white_counts)

    # Make sure we have matrix workspaces before this division
    ConvertToMatrixWorkspace(white_count_mean, white_count_mean)
    ConvertToMatrixWorkspace(sample_counts, sample_counts)
        
    # Normalise the sample run
    sample_counts = Divide(sample_counts, white_count_mean, sample_counts).workspace()
    if comp_white_counts is not None:
        mtd.deleteWorkspace(str(white_count_mean))

    # If we need to remove zeroes as well then set the the low threshold to a tiny positive number
    if remove_zero:
        low_threshold = 1e-40
    else:
        low_threshold = -1.0

    # What shall we call the output
    lhs_names = lhs_info('names')
    if len(lhs_names) > 0:
        ws_name = lhs_names[0]
    else:
        ws_name = '__do_background_test'

    median_test = MedianDetectorTest(sample_counts, ws_name, SignificanceTest=signif,\
                                     LowThreshold=low_threshold, HighThreshold=bkgd_threshold)
    # Remove temporary
    mtd.deleteWorkspace(str(sample_counts))

    num_failed = median_test['NumberOfFailures'].value
    return median_test.workspace(), num_failed
Пример #3
0
    def diagnose(self, white, **kwargs):
        """
            Run diagnostics on the provided workspaces.
            
            This method does some additional processing before moving on to the diagnostics:
              1) Computes the white beam integrals, converting to energy
              2) Computes the background integral using the instrument defined range
              3) Computes a total count from the sample
              
            These inputs are passed to the diagnostics functions
    
            Required inputs:
            
              white  - A workspace, run number or filepath of a white beam run. A workspace is assumed to
                       have simple been loaded and nothing else.
            
            Optional inputs:
              sample - A workspace, run number or filepath of a sample run. A workspace is assumed to
                       have simple been loaded and nothing else. (default = None)
              second_white - If provided an additional set of tests is performed on this. (default = None)
              hard_mask  - A file specifying those spectra that should be masked without testing (default=None)
              tiny        - Minimum threshold for acceptance (default = 1e-10)
              huge        - Maximum threshold for acceptance (default = 1e10)
              bkgd_range - A list of two numbers indicating the background range (default=instrument defaults)
              van_out_lo  - Lower bound defining outliers as fraction of median value (default = 0.01)
              van_out_hi  - Upper bound defining outliers as fraction of median value (default = 100.)
              van_lo      - Fraction of median to consider counting low for the white beam diag (default = 0.1)
              van_hi      - Fraction of median to consider counting high for the white beam diag (default = 1.5)
              van_sig  - Error criterion as a multiple of error bar i.e. to fail the test, the magnitude of the\n"
                          "difference with respect to the median value must also exceed this number of error bars (default=0.0)
              samp_zero    - If true then zeroes in the vanadium data will count as failed (default = True)
              samp_lo      - Fraction of median to consider counting low for the white beam diag (default = 0)
              samp_hi      - Fraction of median to consider counting high for the white beam diag (default = 2.0)
              samp_sig  - Error criterion as a multiple of error bar i.e. to fail the test, the magnitude of the\n"
                          "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
        """
        lhs_names = funcreturns.lhs_info('names')
        if len(lhs_names) > 0:
            var_name = lhs_names[0]
        else:
            var_name = "diag_mask"

        # Check for any keywords that have not been supplied and put in the defaults
        for par in self.diag_params:
            arg = par.lstrip('diag_')
            if arg not in kwargs:
                kwargs[arg] = getattr(self, par)
                
        # Get the white beam vanadium integrals
        whiteintegrals = self.do_white(white, None, None,None) # No grouping yet
        if 'second_white' in kwargs:
            second_white = kwargs['second_white']
            if second_white is None:
                del kwargs['second_white']
            else:
                other_whiteintegrals = self.do_white(second_white, None, None,None) # No grouping yet
                kwargs['second_white'] = other_whiteintegrals

        # Get the background/total counts from the sample if present
        if 'sample' in kwargs:
            sample = kwargs['sample']
            del kwargs['sample']
            # If the bleed test is requested then we need to pass in the sample_run as well
            if kwargs.get('bleed_test', False):
                kwargs['sample_run'] = sample
            
            # Set up the background integrals
            result_ws = common.load_runs(sample)
            result_ws = self.normalise(result_ws, result_ws.name(), self.normalise_method)
            if 'bkgd_range' in kwargs:
                bkgd_range = kwargs['bkgd_range']
                del kwargs['bkgd_range']
            else:
                bkgd_range = self.background_range
            background_int = Integration(result_ws,
                                         RangeLower=bkgd_range[0],RangeUpper=bkgd_range[1],
                                         IncludePartialBins=True)
            total_counts = Integration(result_ws, IncludePartialBins=True)
            background_int = ConvertUnits(background_int, "Energy", AlignBins=0)
            background_int *= 1.7016e8
            diagnostics.normalise_background(background_int, whiteintegrals, kwargs.get('second_white',None))
            kwargs['background_int'] = background_int
            kwargs['sample_counts'] = total_counts
        
        # If we have a hard_mask, check the instrument name is defined
        if 'hard_mask' in kwargs:
            if 'instrument_name' not in kwargs:
                kwargs['instrument_name'] = self.instr_name
        
        # Check how we should run diag
        if self.diag_spectra is None:
            # Do the whole lot at once
            diagnostics.diagnose(whiteintegrals, **kwargs)
        else:
            banks = self.diag_spectra.split(";")
            bank_spectra = []
            for b in banks:
                token = b.split(",")  # b = "(,)"
                if len(token) != 2: 
                    raise ValueError("Invalid bank spectra specification in diag %s" % self.diag_spectra)
                start = int(token[0].lstrip('('))
                end = int(token[1].rstrip(')'))
                bank_spectra.append((start,end))
            
            for index, bank in enumerate(bank_spectra):
                kwargs['start_index'] = bank[0] - 1
                kwargs['end_index'] = bank[1] - 1
                diagnostics.diagnose(whiteintegrals, **kwargs)
                
        if 'sample_counts' in kwargs:
            DeleteWorkspace(Workspace='background_int')
            DeleteWorkspace(Workspace='total_counts')
        if 'second_white' in kwargs:
            DeleteWorkspace(Workspace=kwargs['second_white'])
        # Return a mask workspace
        diag_mask, det_ids = ExtractMask(InputWorkspace=whiteintegrals,OutputWorkspace=var_name)
        DeleteWorkspace(Workspace=whiteintegrals)
        self.spectra_masks = diag_mask
        return diag_mask