Example #1
0
def CalibrateWish(RunNumber, PanelNumber):
    '''
    :param RunNumber: is the run number of the calibration.
    :param PanelNumber: is a string of two-digit number of the panel being calibrated
    '''
    # == Set parameters for calibration ==
    previousDefaultInstrument = config['default.instrument']
    config['default.instrument'] = "WISH"
    filename = str(RunNumber)
    CalibratedComponent = 'WISH/panel' + PanelNumber

    # Get calibration raw file and integrate it
    print "Loading", filename
    rawCalibInstWS = Load(
        filename)  #'raw' in 'rawCalibInstWS' means unintegrated.
    CalibInstWS = Integration(rawCalibInstWS, RangeLower=1, RangeUpper=20000)
    DeleteWorkspace(rawCalibInstWS)
    print "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate"

    # Give y-positions of slit points (gotten for converting first tube's slit point to Y)

    # WISH instrument has a particularity. It is composed by a group of upper tubes and lower tubes,
    # they are disposed 3 milimiters in difference one among the other
    lower_tube = numpy.array(
        [-0.41, -0.31, -0.21, -0.11, -0.02, 0.09, 0.18, 0.28, 0.39])
    upper_tube = numpy.array(lower_tube + 0.003)
    funcForm = 9 * [1]  # 9 gaussian peaks
    print "Created objects needed for calibration."

    # Get the calibration and put it into the calibration table

    #calibrate the lower tubes
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, lower_tube, funcForm,\
                                                  rangeList = range(0,76), outputPeak=True)

    #calibrate the upper tubes
    calibrationTable, peakTable = tube.calibrate(
        CalibInstWS,
        CalibratedComponent,
        upper_tube,
        funcForm,
        rangeList=range(76, 152),
        calibTable=calibrationTable,  #give the calibration table to append data
        outputPeak=peakTable  #give peak table to append data
    )

    print "Got calibration (new positions of detectors)"

    #Apply the calibration
    ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
    print "Applied calibration"

    # == Save workspace ==
    #uncomment these lines to save the workspace
    #nexusName = "TubeCalibDemoWish"+PanelNumber+"Result.nxs"
    #SaveNexusProcessed( CalibInstWS, 'TubeCalibDemoWishResult.nxs',"Result of Running TubeCalibWishMerlin_Simple.py")
    #print "saved calibrated workspace (CalibInstWS) into Nexus file",nexusName

    # == Reset dafault instrument ==
    config['default.instrument'] = previousDefaultInstrument
Example #2
0
def CalibrateWish(run_per_panel_list):
    '''
    :param run_per_panel_list: is a list of tuples with the run number and the associated panel

    run_per_panel_list =  [ (17706, 'panel01'), (17705, 'panel02'),  (17701, 'panel03'), (17702, 'panel04'), (17695, 'panel05')]
    '''
    # == Set parameters for calibration ==
    previousDefaultInstrument = config['default.instrument']
    config['default.instrument']="WISH"

    # definition of the parameters static for the calibration
    lower_tube = numpy.array([-0.41,-0.31,-0.21,-0.11,-0.02, 0.09, 0.18, 0.28, 0.39 ])
    upper_tube = numpy.array(lower_tube+0.003)
    funcForm = 9*[1] # 9 gaussian peaks
    margin = 15
    low_range = range(0,76)
    high_range = range(76,152)
    kwargs = {'margin':margin}

    # it will copy all the data from the runs to have a single instrument with the calibrated data.
    whole_instrument = LoadRaw(str(run_per_panel_list[0][0]))
    whole_instrument = Integration(whole_instrument)


    for (run_number, panel_name) in run_per_panel_list:
        panel_name = str(panel_name)
        run_number = str(run_number)
        # load your data and integrate it
        ws = LoadRaw(run_number, OutputWorkspace=panel_name)
        ws = Integration(ws, 1, 20000, OutputWorkspace=panel_name)

        # use the TubeSpec object to be able to copy the data to the whole_instrument
        tube_set = TubeSpec(ws)
        tube_set.setTubeSpecByString(panel_name)

        # update kwargs argument before calling calibrate
        kwargs['rangeList'] = low_range # calibrate only the lower tubes
        calibrationTable = tube.calibrate(ws, tube_set, lower_tube, funcForm, **kwargs)

        # update kwargs
        kwargs['calibTable'] = calibrationTable # append calib to calibrationtable
        kwargs['rangeList'] = high_range # calibrate only the upper tubes

        calibrationTable = tube.calibrate(ws, tube_set, upper_tube, funcForm, **kwargs)
        kwargs['calibTable'] = calibrationTable

        ApplyCalibration(ws, calibrationTable)

        # copy data from the current panel to the whole_instrument
        for i in range(tube_set.getNumTubes()):
            for spec_num in tube_set.getTube(i):
                whole_instrument.setY(spec_num,ws.dataY(spec_num))

    # calibrate the whole_instrument with the last calibrated panel which has the calibration accumulation
    # of all the others
    CopyInstrumentParameters(run_per_panel_list[-1][1],whole_instrument)

    config['default.instrument'] = previousDefaultInstrument
Example #3
0
def CalibrateWish( run_per_panel_list):
    '''
    :param run_per_panel_list: is a list of tuples with the run number and the associated panel 

    run_per_panel_list =  [ (17706, 'panel01'), (17705, 'panel02'),  (17701, 'panel03'), (17702, 'panel04'), (17695, 'panel05')]
    '''
    # == Set parameters for calibration ==
    previousDefaultInstrument = config['default.instrument']
    config['default.instrument']="WISH"
    
    # definition of the parameters static for the calibration
    lower_tube = numpy.array([-0.41,-0.31,-0.21,-0.11,-0.02, 0.09, 0.18, 0.28, 0.39 ])
    upper_tube = numpy.array(lower_tube+0.003)
    funcForm = 9*[1] # 9 gaussian peaks
    margin = 15
    low_range = range(0,76)
    high_range = range(76,152)
    kwargs = {'margin':margin}

    # it will copy all the data from the runs to have a single instrument with the calibrated data. 
    whole_instrument = LoadRaw(str(run_per_panel_list[0][0]))
    whole_instrument = Integration(whole_instrument)


    for (run_number, panel_name) in run_per_panel_list:        
        panel_name = str(panel_name)
	run_number = str(run_number)
        # load your data and integrate it
        ws = LoadRaw(run_number, OutputWorkspace=panel_name)
        ws = Integration(ws, 1, 20000, OutputWorkspace=panel_name)

        # use the TubeSpec object to be able to copy the data to the whole_instrument
        tube_set = TubeSpec(ws)
        tube_set.setTubeSpecByString(panel_name)
        
        # update kwargs argument before calling calibrate        
        kwargs['rangeList'] = low_range # calibrate only the lower tubes
        calibrationTable = tube.calibrate(ws, tube_set, lower_tube, funcForm, **kwargs)
        
        # update kwargs
        kwargs['calibTable'] = calibrationTable # append calib to calibrationtable
	kwargs['rangeList'] = high_range # calibrate only the upper tubes

        calibrationTable = tube.calibrate(ws, tube_set, upper_tube, funcForm, **kwargs)
        kwargs['calibTable'] = calibrationTable

        ApplyCalibration(ws, calibrationTable)

        # copy data from the current panel to the whole_instrument
        for i in range(tube_set.getNumTubes()):
		for spec_num in tube_set.getTube(i):
			whole_instrument.setY(spec_num,ws.dataY(spec_num))

    # calibrate the whole_instrument with the last calibrated panel which has the calibration accumulation
    # of all the others
    CopyInstrumentParameters(run_per_panel_list[-1][1],whole_instrument)

    config['default.instrument'] = previousDefaultInstrument
def CalibrateWish(RunNumber, PanelNumber):
    '''
    :param RunNumber: is the run number of the calibration.
    :param PanelNumber: is a string of two-digit number of the panel being calibrated
    '''
    # == Set parameters for calibration ==
    previousDefaultInstrument = mantid.config['default.instrument']
    mantid.config['default.instrument'] = "WISH"
    filename = str(RunNumber)
    CalibratedComponent = 'WISH/panel' + PanelNumber

    # Get calibration raw file and integrate it
    print("Loading", filename)
    rawCalibInstWS = mantid.Load(filename)  # 'raw' in 'rawCalibInstWS' means unintegrated.
    CalibInstWS = mantid.Integration(rawCalibInstWS, RangeLower=1, RangeUpper=20000)
    mantid.DeleteWorkspace(rawCalibInstWS)
    print("Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate")

    # Give y-positions of slit points (gotten for converting first tube's slit point to Y)

    # WISH instrument has a particularity. It is composed by a group of upper tubes and lower tubes,
    # they are disposed 3 milimiters in difference one among the other
    lower_tube = numpy.array([-0.41, -0.31, -0.21, -0.11, -0.02, 0.09, 0.18, 0.28, 0.39])
    upper_tube = numpy.array(lower_tube + 0.003)
    funcForm = 9 * [1]  # 9 gaussian peaks
    print("Created objects needed for calibration.")

    # Get the calibration and put it into the calibration table

    # calibrate the lower tubes
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, lower_tube, funcForm,
                                                 rangeList=list(range(0, 76)), outputPeak=True)

    # calibrate the upper tubes
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, upper_tube, funcForm,
                                                 rangeList=list(range(76, 152)),
                                                 calibTable=calibrationTable,
                                                 # give the calibration table to append data
                                                 outputPeak=peakTable  # give peak table to append data
                                                 )

    print("Got calibration (new positions of detectors)")

    # Apply the calibration
    mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
    print("Applied calibration")

    # == Save workspace ==
    # uncomment these lines to save the workspace
    # nexusName = "TubeCalibDemoWish" + PanelNumber + "Result.nxs"
    # mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoWishResult.nxs', "Result of Running TubeCalibWishMerlin_Simple.py")
    # print("saved calibrated workspace (CalibInstWS) into Nexus file", nexusName)

    # == Reset dafault instrument ==
    mantid.config['default.instrument'] = previousDefaultInstrument
Example #5
0
def provideTheExpectedValue(filename):
    """
    Giving the expected value for the position of the peaks in pixel.

    The :func:`~Examples.minimalInput` let to the calibrate to guess the position of the pixels
    among the tubes. Altough it works nicelly, providing these expected values may improve the results.
    This is done through the **fitPar** parameter.
    """
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable = tube.calibrate(CalibInstWS,
                                      CalibratedComponent,
                                      knownPos,
                                      funcFactor,
                                      fitPar=fitPar)
    # == Apply the Calibation ==
    ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #6
0
def minimalInput(filename):
    """
    Simplest way of calling :func:`tube.calibrate`


    The minimal input for the calibration is the integrated workspace
    and the knwon positions.

    Eventhough it is easy to call, the calibration performs well, but there are ways to improve
    the results, as it is explored after.

    .. image:: /images/outputOfMinimalInput.png

    """
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2]

    # == Get the calibration and put results into calibration table ==
    calibrationTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor)
    # == Apply the Calibation ==
    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #7
0
def minimalInput(filename):
    """
    Simplest way of calling :func:`tube.calibrate`


    The minimal input for the calibration is the integrated workspace
    and the knwon positions.

    Eventhough it is easy to call, the calibration performs well, but there are ways to improve
    the results, as it is explored after.

    .. image:: /images/outputOfMinimalInput.png

    """
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2]

    # == Get the calibration and put results into calibration table ==
    calibrationTable = tube.calibrate(CalibInstWS, CalibratedComponent,
                                      knownPos, funcFactor)
    # == Apply the Calibation ==
    ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #8
0
def provideTheExpectedValue(filename):
    """
    Giving the expected value for the position of the peaks in pixel.

    The :func:`~Examples.minimalInput` let to the calibrate to guess the position of the pixels
    among the tubes. Altough it works nicelly, providing these expected values may improve the results.
    This is done through the **fitPar** parameter.
    """
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                      fitPar=fitPar)
    # == Apply the Calibation ==
    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #9
0
def improvingCalibrationOfListOfTubes(filename):
    """
    Analysing the result of provideTheExpectedValue it was seen that the calibration
    of some tubes was not good.

    .. note::
          This method list some of them, there are a group belonging to window B2 that shows
          only 2 peaks that are not dealt with here.

    If first plot the bad ones using the **plotTube** option. It them, find where they fail, and how
    to correct their peaks, using the **overridePeaks**.
    If finally, applies the calibration again with the points corrected.
    """
    from tube_calib_fit_params import TubeCalibFitParams

    not_good = [19,37, 71, 75, 181, 186, 234, 235, 245, 273, 345]

    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    #calibrationTable, peakTable= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
    #	fitPar=fitPar, outputPeak=True, plotTube=not_good, rangeList=not_good)

    #CalibInstWS = loadingStep(filename)

    # it is defined as the mean values around the neighbours
    define_peaks = {19:[10, 80.9771, 123.221, 164.993, 245.717], # the first one was bad
                    37: [6.36, 80.9347, 122.941, 165.104, 248.32], # the first one was bad
                    71: [8.62752, 85.074, 124.919, 164.116, 246.82 ], # the last one was bad - check if we can inprove
                    75: [14.4285, 90.087, 128.987, 167.047, 242.62], # the last one was bad - check if we can inprove
                    181: [11.726, 94.0496, 137.816,  180, 255], # the third peak was lost
                    186:[11.9382, 71.5203, 107, 147.727, 239.041], #lost the second peak
                    234: [4.84, 82.7824, 123.125, 163.945, 241.877], # the first one was bad
                    235: [4.84, 80.0077, 121.002, 161.098, 238.502], # the first one was bad
                    245: [9.88089, 93.0593, 136.911, 179.5, 255], # the third peak was bad
                    273: [18.3711, 105.5, 145.5, 181.6, 243.252], # lost first and third peaks
                    345: [4.6084, 87.0351, 128.125, 169.923, 245.3] # the last one was bad
                   }
    calibrationTable, peakTable= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                                fitPar=fitPar, outputPeak=True, overridePeaks=define_peaks)

    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #10
0
def improvingCalibrationOfListOfTubes(filename):
    """
    Analysing the result of provideTheExpectedValue it was seen that the calibration
    of some tubes was not good.

    .. note::
          This method list some of them, there are a group belonging to window B2 that shows
          only 2 peaks that are not dealt with here.

    If first plot the bad ones using the **plotTube** option. It them, find where they fail, and how
    to correct their peaks, using the **overridePeaks**.
    If finally, applies the calibration again with the points corrected.
    """
    from tube_calib_fit_params import TubeCalibFitParams

    # not_good = [19,37, 71, 75, 181, 186, 234, 235, 245, 273, 345]

    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole instrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    # calibrationTable, peakTable= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
    #	fitPar=fitPar, outputPeak=True, plotTube=not_good, rangeList=not_good)

    # CalibInstWS = loadingStep(filename)

    # it is defined as the mean values around the neighbours
    define_peaks = {19: [10, 80.9771, 123.221, 164.993, 245.717],  # the first one was bad
                    37: [6.36, 80.9347, 122.941, 165.104, 248.32],  # the first one was bad
                    71: [8.62752, 85.074, 124.919, 164.116, 246.82],  # the last one was bad - check if we can inprove
                    75: [14.4285, 90.087, 128.987, 167.047, 242.62],  # the last one was bad - check if we can inprove
                    181: [11.726, 94.0496, 137.816, 180, 255],  # the third peak was lost
                    186: [11.9382, 71.5203, 107, 147.727, 239.041],  # lost the second peak
                    234: [4.84, 82.7824, 123.125, 163.945, 241.877],  # the first one was bad
                    235: [4.84, 80.0077, 121.002, 161.098, 238.502],  # the first one was bad
                    245: [9.88089, 93.0593, 136.911, 179.5, 255],  # the third peak was bad
                    273: [18.3711, 105.5, 145.5, 181.6, 243.252],  # lost first and third peaks
                    345: [4.6084, 87.0351, 128.125, 169.923, 245.3]  # the last one was bad
                    }
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                                 fitPar=fitPar, outputPeak=True, overridePeaks=define_peaks)

    mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #11
0
def changeMarginAndExpectedValue(filename):
    """
    To fit correctly, it is important to have a good window around the peak. This windown is defined
    by the **margin** parameter.

    This examples shows how the results worsen if we change the margin from its default value **15**
    to **10**.

    It shows how to see the fitted values using the **plotTube** parameter.

    It will also output the peaks position and save them, through the **outputPeak** option and
    the :func:`tube.savePeak` method.

    An example of the fitted data compared to the acquired data to find the peaks positions:

    .. image:: /images/calibratePlotFittedData.png

    The result deteriorate, as you can see:

    .. image:: /images/calibrateChangeMarginAndExpectedValue.png

    """
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole instrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 knownPos,
                                                 funcFactor,
                                                 fitPar=fitPar,
                                                 plotTube=[1, 10, 100],
                                                 outputPeak=True,
                                                 margin=10)
    # == Apply the Calibation ==
    mantid.ApplyCalibration(Workspace=CalibInstWS,
                            CalibrationTable=calibrationTable)

    tube.savePeak(peakTable, 'TubeDemoMaps01.txt')
Example #12
0
def calibrateB2Window(filename):
    """
    There are among the B2 window tubes, some tubes that are showing only 2 strips.

    Those tubes must be calibrated separated, as the known positions are not valid.

    This example calibrate them, using only 4 known values: 2 edges and 2 peaks.

    Run this example, and them see the worksapce in the calibrated instrument and you will see
    how it worked.

    The picture shows the output, look that only a section of the B2 Window was calibrated.

    .. image:: /images/calibrateB2Window.png

    """
    from tube_calib_fit_params import TubeCalibFitParams
    # b2 with 2 peaks range
    b2_range = list(range(196, 212)) + list(range(222, 233))

    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole instrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, 0.16, 0.50], [2, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable = tube.calibrate(
        CalibInstWS,
        CalibratedComponent,
        knownPos,
        funcFactor,
        fitPar=fitPar,
        outputPeak=True,
        plotTube=[b2_range[0], b2_range[-1]],
        rangeList=b2_range)

    mantid.ApplyCalibration(Workspace=CalibInstWS,
                            CalibrationTable=calibrationTable)
Example #13
0
def changeMarginAndExpectedValue(filename):
    """
    To fit correcly, it is important to have a good window around the peak. This windown is defined
    by the **margin** parameter.

    This examples shows how the results worsen if we change the margin from its default value **15**
    to **10**.

    It shows how to see the fitted values using the **plotTube** parameter.

    It will also output the peaks position and save them, through the **outputPeak** option and
    the :func:`tube.savePeak` method.

    An example of the fitted data compared to the acquired data to find the peaks positions:

    .. image:: /images/calibratePlotFittedData.png

    The result deteriorate, as you can see:

    .. image:: /images/calibrateChangeMarginAndExpectedValue.png

    """
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                                fitPar=fitPar, plotTube=[1,10,100], outputPeak=True, margin=10)
    # == Apply the Calibation ==
    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)

    tube.savePeak(peakTable, 'TubeDemoMaps01.txt')
def calibrateB2Window(filename):
    """
    There are among the B2 window tubes, some tubes that are showing only 2 strips.

    Those tubes must be calibrated separated, as the known positions are not valid.

    This example calibrate them, using only 4 known values: 2 edges and 2 peaks.

    Run this example, and them see the worksapce in the calibrated instrument and you will see
    how it worked.

    The picture shows the output, look that only a section of the B2 Window was calibrated.

    .. image:: /images/calibrateB2Window.png

    """
    from tube_calib_fit_params import TubeCalibFitParams
    # b2 with 2 peaks range
    b2_range = list(range(196, 212)) + list(range(222, 233))

    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole instrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, 0.16, 0.50], [2, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                                 fitPar=fitPar, outputPeak=True, plotTube=[b2_range[0], b2_range[-1]],
                                                 rangeList=b2_range)

    mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #15
0
def completeCalibration(filename):
    """
    This example shows how to use some properties of calibrate method to
    join together the calibration done in :func:`provideTheExpectedValue`,
    and improved in :func:`calibrateB2Window`, and :func:`improvingCalibrationOfListOfTubes`.

    It also improves the result of the calibration because it deals with the E door. The
    aquired data cannot be used to calibrate the E door, and trying to do so, produces a bad
    result. In this example, the tubes inside the E door are excluded to the calibration.
    Using the '''rangeList''' option.
    """

    # first step, load the workspace
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)


    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all

    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)


    #execute the improvingCalibrationOfListOfTubes excluding the range of b2 window
    # correct the definition of the peaks for the folowing indexes
    #define_peaks = {19:[10, 80.9771, 123.221, 164.993, 245.717], # the first one was bad
    #	37: [6.36, 80.9347, 122.941, 165.104, 248.32], # the first one was bad
    #	71: [8.62752, 85.074, 124.919, 164.116, 246.82 ], # the last one was bad - check if we can inprove
    #	75: [14.4285, 90.087, 128.987, 167.047, 242.62], # the last one was bad - check if we can inprove
    #	181: [11.726, 94.0496, 137.816,  180, 255], # the third peak was lost
    #	186:[11.9382, 71.5203, 107, 147.727, 239.041], #lost the second peak
    #	234: [4.84, 82.7824, 123.125, 163.945, 241.877], # the first one was bad
    #	235: [4.84, 80.0077, 121.002, 161.098, 238.502], # the first one was bad
    #	245: [9.88089, 93.0593, 136.911, 179.5, 255], # the third peak was bad
    #	273: [18.3711, 105.5, 145.5, 181.6, 243.252],# lost first and third peaks
    #	345: [4.6084, 87.0351, 128.125, 169.923, 245.3]} # the last one was bad
    define_peaks = {19:[10, 80.9771, 123.221, 164.993, 245.717],\
    	37: [6.36, 80.9347, 122.941, 165.104, 248.32],\
    	71: [8.62752, 85.074, 124.919, 164.116, 246.82 ],\
    	75: [14.4285, 90.087, 128.987, 167.047, 242.62],\
    	181: [11.726, 94.0496, 137.816,  180, 255],\
    	186:[11.9382, 71.5203, 107, 147.727, 239.041],\
    	234: [4.84, 82.7824, 123.125, 163.945, 241.877],\
    	235: [4.84, 80.0077, 121.002, 161.098, 238.502],\
    	245: [9.88089, 93.0593, 136.911, 179.5, 255],\
    	273: [18.3711, 105.5, 145.5, 181.6, 243.252],\
    	345: [4.6084, 87.0351, 128.125, 169.923, 245.3]}

    b2_window = range(196,212) + range(222,233)

    complete_range = range(648)

    # this data can not be used to calibrate the E1 window, so, let's remove it.
    e1_window = range(560,577)
    aux = numpy.setdiff1d(complete_range, b2_window)
    # the group that have 3 stripts are all the tubes except the b2 window and e window.
    range_3_strips = numpy.setdiff1d(aux, e1_window)

    calibrationTable, peak3Table= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,\
    	fitPar=fitPar, outputPeak=True, overridePeaks=define_peaks, rangeList=range_3_strips)

    # now calibrate the b2_window REMOVE SECOND PEAK
    # define the known positions and function factor (edge, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16, 0.16, 0.50 ],[2,1,1,2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # apply the calibration for the b2_window 2 strips values
    calibrationTable, peak2Table = tube.calibrate(CalibInstWS, CalibratedComponent,
                                                  knownPos,  #these parameters now have only 4 points
                                                  funcFactor,
                                                  fitPar=fitPar,
                                                  outputPeak=True,
                                                  calibTable = calibrationTable, # it will append to the calibTable
                                                  rangeList = b2_window)

    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #16
0
def findThoseTubesThatNeedSpecialCareForCalibration(filename):
    """
    The example :func:`provideTheExpectedValue` has shown its capability to calibrate almost
    all tubes, but,    as explored in the :func:`improvingCalibrationOfListOfTubes` and
    :func:`improvingCalibrationSingleTube` there are
    some tubes that could not be calibrated using that method.

    The goal of this method is to show one way to find the tubes that will require special care.

    It will first perform the same calibration seen in :func:`provideTheExpectedValue`,
    them, it will process the **peakTable** output of the calibrate method when enabling the
    parameter **outputPeak**.

    It them creates the Peaks workspace, that is the diffence of the peaks position from the
    expected values of the peaks positions for all the tubes. This allows to spot what are the
    tubes whose fitting are outliers in relation to the others.

    .. image:: /images/plotingPeaksDifference.png

    The final result for this method is to output using **plotTube** the result of the fitting
    to all the 'outliers' tubes.
    """
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                                fitPar=fitPar, outputPeak=True)

    # == now, lets investigate the peaks

    #parsing the peakTable to produce a numpy array with dimension (number_of_tubes x number_of_peaks)
    print 'parsing the peak table'
    n = len(peakTable)
    peaksId = n*['']
    data = numpy.zeros((n,5))
    line = 0
    for row in peakTable:
        data_row = [row['Peak%d'%(i)] for i in [1,2,3,4,5]]
        data[line,:] = data_row
        peaksId[line] = row['TubeId']
        line+=1
    # data now has all the peaks positions for each tube
    # the mean value is the expected value for the peak position for each tube
    expected_peak_pos = numpy.mean(data,axis=0)
    #calculate how far from the expected position each peak position is
    distance_from_expected =  numpy.abs(data - expected_peak_pos)

    print 'Creating the Peaks Workspace that shows the distance from the expected value for all peaks for each tube'
    # Let's see these peaks:
    Peaks = CreateWorkspace(range(n),distance_from_expected,NSpec=5)

    # plot all the 5 peaks for Peaks Workspace. You will see that most of the tubes differ
    # at most 12 pixels from the expected values.

    #so let's investigate those that differ more than 12
    # return an array with the indexes for the first axis which is the tube indentification
    check = numpy.where(distance_from_expected > 12)[0]

    #remove repeated values
    #select only those tubes inside the problematic_tubes
    problematic_tubes = list(set(check))

    print 'Tubes whose distance is far from the expected value: ', problematic_tubes

    print 'Calibrating again only these tubes'
    #let's confir that our suspect works
    CalibInstWS = loadingStep(filename)
    calibrationTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,\
    	fitPar=fitPar, rangeList= problematic_tubes, plotTube=problematic_tubes)
Example #17
0
def improvingCalibrationSingleTube(filename):
    """
    The :func:`~Examples.provideTheExpectedValue` provided a good solution, but there are few
    tubes whose calibration was not so good.

    This method explores how to deal with these tubes.

    First of all, it is important to identify the tubes that did not work well.

    From the outputs of provideTheExpectedValue, looking inside the instrument tree,
    it is possible to list all the tubes that are not so good.

    Unfortunatelly, they do not have a single name identifier.
    So, locating them it is a little bit trickier.
    The :func:`~Examples.findThoseTubesThatNeedSpecialCareForCalibration` shows one way of finding those
    tubes.     The index is the position inside the PeakTable.

    For this example, we have used inspection from the Instrument View.
    One of them is inside the A1_Window, 3rd PSD_TUBE_STRIP 8 pack up, 4th PSD_TUBE_STRIP: Index = 8+8+4 - 1 = 19.

    In this example, we will ask the calibration to run the calibration only for 3 tubes
    (indexes 18,19,20). Them, we will check why the 19 is not working well. Finally, we will try to
    provide another peaks position for this tube,
    and run the calibration again for these tubes, to improve the results.

    This example shows how to use **overridePeaks** option
    """
    from tube_calib_fit_params import TubeCalibFitParams
    import time
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50,-0.16,-0.00, 0.16, 0.50 ],[2,1,1,1,2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                                fitPar=fitPar, outputPeak=True, plotTube=[18,19,20], rangeList=[18,19,20])

    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)


    # reload to reset the calibration applied
    CalibInstWS = loadingStep(filename)
    # looking into the second line of calibrationTable, you will see that it defines the peaks for the first position
    # as 14.9788, -0.303511, 9.74828
    # let's change the peak from  -0.303511 to 8.14

    #to override the peaks definition, we use the overridePeaks
    overridePeaks = {19: [8.14, 80.9771, 123.221, 164.993, 245.717]}

    # == Get the calibration and put results into calibration table ==
    # we will not plot anymore, because it will not plot the overrided peaks
    calibrationTable, peakTable= tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcFactor,
                                                fitPar=fitPar, outputPeak=True, rangeList=[18,19,20], overridePeaks=overridePeaks)

    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
Example #18
0
import os
from mantid.simpleapi import *
from mantid import api
import numpy as np
import tube
ws = Load("MER31013.n003")
ws = Integration(ws, 1500, 9000)
pos = [0.84, 0.44, 0.02, -0.45, -0.65]
tt = [1, 1, 1, 1, 1]
calt = tube.calibrate(ws, "MERLIN", pos, tt)
print "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate"

# == Create Objects needed for calibration ==

# Specify components to calibrate
thisTubeSet = TubeSpec(CalibInstWS)
thisTubeSet.setTubeSpecByString(CalibratedComponent1)
thisTubeSet.setTubeSpecByString(CalibratedComponent2)

# Specify the known positions
knownPos = [-0.50,-0.16,-0.00, 0.16, 0.50 ]
funcForm = [2,1,1,1,2]

print "Created objects needed for calibration."

# == Get the calibration and put results into calibration table ==

calibrationTable, peakTable = tube.calibrate(CalibInstWS, thisTubeSet, knownPos, funcForm,
    outputPeak=True)
print "Got calibration (new positions of detectors) "

# == Apply the Calibation ==
ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
print "Applied calibration"


# == Save workspace ==
#SaveNexusProcessed( CalibInstWS, path+'TubeCalibDemoMapsResult.nxs',"Result of Running TCDemoMaps.py")
print "saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs"

Example #20
0
               RewriteSpectraMap='False')
ws = Integration(ws)
CloneWorkspace(InputWorkspace='ws', OutputWorkspace='ws2')
CloneWorkspace(InputWorkspace='ws', OutputWorkspace='ws1')

tubeSet = TubeSpec(ws)
tubeSet.setTubeSpecByStringArray(["bank33", "bank45", "bank57"])

a = (2 * 25.4 + 2) / 1000
knownPositions = np.arange(-7.5 * a, 8.5 * a, a)
funcForm = [1] * 16

calibTable = tube.calibrate(ws,
                            tubeSet,
                            knownPositions,
                            funcForm,
                            margin=6,
                            plotTube=True,
                            outputPeak=True)

ApplyCalibration(Workspace='ws2', PositionTable='CalibTable')

calibTable1 = tube.calibrate(ws,
                             tubeSet,
                             knownPositions,
                             funcForm,
                             margin=6,
                             fitPolyn=1)

ApplyCalibration(Workspace='ws1', PositionTable='CalibTable')
# The positions of the shadows and ends here are an intelligent guess.
# First array gives positions in Metres and second array gives type 1=Gaussian peak 2=edge.

knownPos = [-0.65, -0.22, -0.00, 0.22, 0.65]
funcForm = [2, 1, 1, 1, 2]

# Get fitting parameters
# Set initial parameters for peak finding
ExpectedHeight = -1000.0  # Expected Height of Gaussian Peaks (initial value of fit parameter)
ExpectedWidth = 8.0  # Expected width of Gaussian peaks in pixels  (initial value of fit parameter)
ExpectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]  # Expected positions of the edges and Gaussian peaks
# in pixels (initial values of fit parameters)
fitPar = TubeCalibFitParams(ExpectedPositions, ExpectedHeight, ExpectedWidth)
fitPar.setAutomatic(True)

print("Created objects needed for calibration.")

# == Get the calibration and put results into calibration table ==
calibrationTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcForm,
                                  fitPar=fitPar)
print("Got calibration (new positions of detectors) ")

# == Apply the Calibation ==
mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
print("Applied calibration")

# == Save workspace ==
# mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoMapsResult.nxs', "Result of Running TCDemoMaps.py")
# print("saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs")
CalibInstWS = mantid.Integration( rawCalibInstWS, RangeLower=1, RangeUpper=20000 )
mantid.DeleteWorkspace(rawCalibInstWS)
print("Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate")

CalibratedComponent = 'WISH/panel03/tube038'

# Set fitting parameters
eP = [65.0, 113.0, 161.0, 209.0, 257.0, 305.0, 353.0, 401.0, 449.0]
ExpectedHeight = 2000.0 # Expected Height of Gaussian Peaks (initial value of fit parameter)
ExpectedWidth = 32.0 # Expected width of Gaussian peaks in pixels  (initial value of fit parameter)
fitPar = TubeCalibFitParams( eP, ExpectedHeight, ExpectedWidth )
fitPar.setAutomatic(True)
print("Created objects needed for calibration.")
func_form = 9*[1]

# Use first tube as ideal tube
tube1 = TubeSpec(CalibInstWS)
tube1.setTubeSpecByString('WISH/panel03/tube038')
iTube = tube_calib.constructIdealTubeFromRealTube( CalibInstWS, tube1, fitPar, func_form)

known_pos = iTube.getArray()
print(known_pos)

# Get the calibration and put it into the calibration table
calibrationTable = tube.calibrate( CalibInstWS, 'WISH/panel03', known_pos, func_form, fitPar=fitPar)
print("Got calibration (new positions of detectors)")

#Apply the calibration
mantid.ApplyCalibration(Workspace=CalibInstWS, CalibrationTable=calibrationTable)
print("Applied calibration")
Example #23
0
    def runTest(self):
        # This script calibrates WISH using known peak positions from
        # neutron absorbing bands. The workspace with suffix "_calib"
        # contains calibrated data. The workspace with suxxic "_corrected"
        # contains calibrated data with known problematic tubes also corrected

        ws = mantid.LoadNexusProcessed(Filename="WISH30541_integrated.nxs")

        # This array defines the positions of peaks on the detector in
        # meters from the center (0)

        # For wish this is calculated as follows:
        # Height of all 7 bands = 0.26m => each band is separated by 0.260 / 6 = 0.4333m

        # The bands are on a cylinder diameter 0.923m. So we can work out the angle as
        # (0.4333 * n) / (0.923 / 2) where n is the number of bands above (or below) the
        # center band.

        # Putting this together with the distance to the detector tubes (2.2m) we get
        # the following:  (0.4333n) / 0.4615 * 2200 = Expected peak positions
        # From this we can show there should be 5 peaks (peaks 6 + 7 are too high/low)
        # at: 0, 0.206, 0.413 respectively (this is symmetrical so +/-)

        peak_positions = np.array([-0.413, -0.206, 0, 0.206, 0.413])
        funcForm = 5 * [1]  # 5 gaussian peaks
        fitPar = TubeCalibFitParams([59, 161, 258, 353, 448])
        fitPar.setAutomatic(True)

        instrument = ws.getInstrument()
        spec = TubeSpec(ws)

        spec.setTubeSpecByString(instrument.getFullName())

        idealTube = IdealTube()
        idealTube.setArray(peak_positions)

        # First calibrate all of the detectors
        calibrationTable, peaks = tube.calibrate(ws, spec, peak_positions, funcForm, margin=15,
                                                 outputPeak=True, fitPar=fitPar)
        self.calibration_table = calibrationTable

        def findBadPeakFits(peaksTable, threshold=10):
            """ Find peaks whose fit values fall outside of a given tolerance
            of the mean peak centers across all tubes.

            Tubes are defined as have a bad fit if the absolute difference
            between the fitted peak centers for a specific tube and the
            mean of the fitted peak centers for all tubes differ more than
            the threshold parameter.

            @param peakTable: the table containing fitted peak centers
            @param threshold: the tolerance on the difference from the mean value
            @return A list of expected peak positions and a list of indices of tubes
            to correct
            """
            n = len(peaksTable)
            num_peaks = peaksTable.columnCount() - 1
            column_names = ['Peak%d' % i for i in range(1, num_peaks + 1)]
            data = np.zeros((n, num_peaks))
            for i, row in enumerate(peaksTable):
                data_row = [row[name] for name in column_names]
                data[i, :] = data_row

            # data now has all the peaks positions for each tube
            # the mean value is the expected value for the peak position for each tube
            expected_peak_pos = np.mean(data, axis=0)

            # calculate how far from the expected position each peak position is
            distance_from_expected = np.abs(data - expected_peak_pos)
            check = np.where(distance_from_expected > threshold)[0]
            problematic_tubes = list(set(check))
            print("Problematic tubes are: " + str(problematic_tubes))
            return expected_peak_pos, problematic_tubes

        def correctMisalignedTubes(ws, calibrationTable, peaksTable, spec, idealTube, fitPar, threshold=10):
            """ Correct misaligned tubes due to poor fitting results
            during the first round of calibration.

            Misaligned tubes are first identified according to a tolerance
            applied to the absolute difference between the fitted tube
            positions and the mean across all tubes.

            The FindPeaks algorithm is then used to find a better fit
            with the ideal tube positions as starting parameters
            for the peak centers.

            From the refitted peaks the positions of the detectors in the
            tube are recalculated.

            @param ws: the workspace to get the tube geometry from
            @param calibrationTable: the calibration table output from running calibration
            @param peaksTable: the table containing the fitted peak centers from calibration
            @param spec: the tube spec for the instrument
            @param idealTube: the ideal tube for the instrument
            @param fitPar: the fitting parameters for calibration
            @param threshold: tolerance defining is a peak is outside of the acceptable range
            @return table of corrected detector positions
            """
            table_name = calibrationTable.name() + 'Corrected'
            corrections_table = mantid.CreateEmptyTableWorkspace(OutputWorkspace=table_name)
            corrections_table.addColumn('int', "Detector ID")
            corrections_table.addColumn('V3D', "Detector Position")

            mean_peaks, bad_tubes = findBadPeakFits(peaksTable, threshold)

            for index in bad_tubes:
                print("Refitting tube %s" % spec.getTubeName(index))
                tube_dets, _ = spec.getTube(index)
                getPoints(ws, idealTube.getFunctionalForms(), fitPar, tube_dets)
                tube_ws = mantid.mtd['TubePlot']
                fit_ws = mantid.FindPeaks(InputWorkspace=tube_ws, WorkspaceIndex=0,
                                          PeakPositions=fitPar.getPeaks(), PeaksList='RefittedPeaks')
                centers = [row['centre'] for row in fit_ws]
                detIDList, detPosList = getCalibratedPixelPositions(ws, centers, idealTube.getArray(), tube_dets)

                for id, pos in zip(detIDList, detPosList):
                    corrections_table.addRow({'Detector ID': id, 'Detector Position': kernel.V3D(*pos)})

            return corrections_table

        corrected_calibration_table = correctMisalignedTubes(ws, calibrationTable, peaks, spec, idealTube, fitPar)
        self.correction_table = corrected_calibration_table
        tube.saveCalibration(self.correction_table.getName(), out_path=self.calibration_out_path)
        tube.saveCalibration(self.calibration_table.getName(), out_path=self.correction_out_path)
Example #24
0
CalibInstWS = mantid.Integration( rawCalibInstWS, RangeLower=1, RangeUpper=20000 )
mantid.DeleteWorkspace(rawCalibInstWS)
print("Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate")

CalibratedComponent = 'WISH/panel03/tube038'

# Set fitting parameters
eP = [65.0, 113.0, 161.0, 209.0, 257.0, 305.0, 353.0, 401.0, 449.0]
ExpectedHeight = 2000.0 # Expected Height of Gaussian Peaks (initial value of fit parameter)
ExpectedWidth = 32.0 # Expected width of Gaussian peaks in pixels  (initial value of fit parameter)
fitPar = TubeCalibFitParams( eP, ExpectedHeight, ExpectedWidth )
fitPar.setAutomatic(True)
print("Created objects needed for calibration.")
func_form = 9*[1]

# Use first tube as ideal tube
tube1 = TubeSpec(CalibInstWS)
tube1.setTubeSpecByString('WISH/panel03/tube038')
iTube = tube_calib.constructIdealTubeFromRealTube( CalibInstWS, tube1, fitPar, func_form)

known_pos = iTube.getArray()
print(known_pos)

# Get the calibration and put it into the calibration table
calibrationTable = tube.calibrate( CalibInstWS, 'WISH/panel03', known_pos, func_form, fitPar=fitPar)
print("Got calibration (new positions of detectors)")

#Apply the calibration
mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
print("Applied calibration")
def CalibrateMerlin(RunNumber):
    # == Set parameters for calibration ==
    previousDefaultInstrument = mantid.config['default.instrument']
    mantid.config['default.instrument'] = "MERLIN"
    filename = str(RunNumber)  # Name of calibration run.
    rangeLower = 3000  # Integrate counts in each spectra from rangeLower to rangeUpper
    rangeUpper = 20000  #

    # Set parameters for ideal tube.
    Left = 2.0  # Where the left end of tube should be in pixels (target for AP)
    Centre = 512.5  # Where the centre of the tube should be in pixels (target for CP)
    Right = 1023.0  # Where the right of the tube should be in pixels (target for BP)
    ActiveLength = 2.9  # Active length of tube in Metres

    # Set initial parameters for peak finding
    ExpectedHeight = 1000.0  # Expected Height of Gaussian Peaks (initial value of fit parameter)
    ExpectedWidth = 32.0  # Expected width of centre peak in Pixels (initial value of fit parameter)
    ExpectedPositions = [35.0, 512.0,
                         989.0]  # Expected positions of the edges and peak in pixels (initial values of fit parameters)

    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MERLIN'  # Calibrate door 2

    # Get calibration raw file and integrate it
    print(filename)
    rawCalibInstWS = mantid.LoadRaw(filename)
    # 'raw' in 'rawCalibInstWS' means unintegrated.
    print("Integrating Workspace")
    CalibInstWS = mantid.Integration(rawCalibInstWS, RangeLower=rangeLower, RangeUpper=rangeUpper)
    mantid.DeleteWorkspace(rawCalibInstWS)
    print("Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate")

    # == Create Objects needed for calibration ==

    ## In the merlin case, the positions are usually given in pixels, instead of being given in
    ## meters, to convert to meter and put the origin in the center, we have to apply the following
    ## transformation:
    ##
    ## pos = pixel * length/npixels - length/2 = length (pixel/npixels - 1/2)
    ##
    ## for merlin: npixels = 1024

    knownPos = ActiveLength * (numpy.array([Left, Centre, Right]) / 1024.0 - 0.5)
    funcForm = 3 * [1]

    # Get fitting parameters
    fitPar = TubeCalibFitParams(ExpectedPositions, ExpectedHeight, ExpectedWidth, margin=40)

    print("Created objects needed for calibration.")

    # == Get the calibration and put results into calibration table ==
    # also put peaks into PeakFile
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcForm,
                                                 outputPeak=True, fitPar=fitPar, plotTube=list(range(0, 280, 20)))
    print("Got calibration (new positions of detectors) and put slit peaks into file TubeDemoMerlin01.txt")

    # == Apply the Calibation ==
    mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
    print("Applied calibration")

    # == Save workspace ==
    # mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoMerlinResult.nxs', "Result of Running TubeCalibDemoMerlin_Simple.py")
    # print("saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMerlinResult.nxs")

    # == Reset dafault instrument ==
    mantid.config['default.instrument'] = previousDefaultInstrument
Example #26
0
import os
from mantid.simpleapi import *
from mantid import api
import numpy as np
import tube
ws = Load("MER31013.n003")
ws = Integration(ws,1500,9000)
pos = [0.84,0.44,0.02,-0.45,-0.65]
tt = [1,1,1,1,1]
calt = tube.calibrate(ws,"MERLIN",pos,tt)
Example #27
0
# == Create Objects needed for calibration ==
# The positions of the shadows and ends here are an intelligent guess.
# First array gives positions in Metres and second array gives type 1=Gaussian peak 2=edge.
# See http://www.mantidproject.org/IdealTube for details.
knownPos = [-0.50, -0.165, -0.00, 0.165, 0.50]
funcForm = [2, 1, 1, 1, 2]

# Get fitting parameters
fitPar = TubeCalibFitParams(ExpectedPositions, ExpectedHeight, ExpectedWidth)
fitPar.setAutomatic(True)

print("Created objects needed for calibration.")

# == Get the calibration and put results into calibration table ==
# also put peaks into PeakFile
calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, knownPos, funcForm,
                                             fitPar=fitPar, outputPeak=True)
print("Got calibration (new positions of detectors) ")

# == Apply the Calibation ==
mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
print("Applied calibration")

# == Save workspace ==
mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoMapsResult.nxs', "Result of Running TCDemoMaps_B1.py")
print("saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs")

# == Save Peak File ==
tube.savePeak(peakTable, 'TubeDemoMaps01.txt')
Example #28
0
    def runTest(self):
        # This script calibrates WISH using known peak positions from
        # neutron absorbing bands. The workspace with suffix "_calib"
        # contains calibrated data. The workspace with suxxic "_corrected"
        # contains calibrated data with known problematic tubes also corrected

        ws = mantid.LoadNexusProcessed(Filename="WISH30541_integrated.nxs")

        # This array defines the positions of peaks on the detector in
        # meters from the center (0)

        # For wish this is calculated as follows:
        # Height of all 7 bands = 0.26m => each band is separated by 0.260 / 6 = 0.4333m

        # The bands are on a cylinder diameter 0.923m. So we can work out the angle as
        # (0.4333 * n) / (0.923 / 2) where n is the number of bands above (or below) the
        # center band.

        # Putting this together with the distance to the detector tubes (2.2m) we get
        # the following:  (0.4333n) / 0.4615 * 2200 = Expected peak positions
        # From this we can show there should be 5 peaks (peaks 6 + 7 are too high/low)
        # at: 0, 0.206, 0.413 respectively (this is symmetrical so +/-)

        peak_positions = np.array([-0.413, -0.206, 0, 0.206, 0.413])
        funcForm = 5 * [1]  # 5 gaussian peaks
        fitPar = TubeCalibFitParams([59, 161, 258, 353, 448])
        fitPar.setAutomatic(True)

        instrument = ws.getInstrument()
        spec = TubeSpec(ws)

        spec.setTubeSpecByString(instrument.getFullName())

        idealTube = IdealTube()
        idealTube.setArray(peak_positions)

        # First calibrate all of the detectors
        calibrationTable, peaks = tube.calibrate(ws, spec, peak_positions, funcForm, margin=15,
                                                 outputPeak=True, fitPar=fitPar)
        self.calibration_table = calibrationTable

        def findBadPeakFits(peaksTable, threshold=10):
            """ Find peaks whose fit values fall outside of a given tolerance
            of the mean peak centers across all tubes.

            Tubes are defined as have a bad fit if the absolute difference
            between the fitted peak centers for a specific tube and the
            mean of the fitted peak centers for all tubes differ more than
            the threshold parameter.

            @param peakTable: the table containing fitted peak centers
            @param threshold: the tolerance on the difference from the mean value
            @return A list of expected peak positions and a list of indices of tubes
            to correct
            """
            n = len(peaksTable)
            num_peaks = peaksTable.columnCount() - 1
            column_names = ['Peak%d' % i for i in range(1, num_peaks + 1)]
            data = np.zeros((n, num_peaks))
            for i, row in enumerate(peaksTable):
                data_row = [row[name] for name in column_names]
                data[i, :] = data_row

            # data now has all the peaks positions for each tube
            # the mean value is the expected value for the peak position for each tube
            expected_peak_pos = np.mean(data, axis=0)

            # calculate how far from the expected position each peak position is
            distance_from_expected = np.abs(data - expected_peak_pos)
            check = np.where(distance_from_expected > threshold)[0]
            problematic_tubes = list(set(check))
            print("Problematic tubes are: " + str(problematic_tubes))
            return expected_peak_pos, problematic_tubes

        def correctMisalignedTubes(ws, calibrationTable, peaksTable, spec, idealTube, fitPar, threshold=10):
            """ Correct misaligned tubes due to poor fitting results
            during the first round of calibration.

            Misaligned tubes are first identified according to a tolerance
            applied to the absolute difference between the fitted tube
            positions and the mean across all tubes.

            The FindPeaks algorithm is then used to find a better fit
            with the ideal tube positions as starting parameters
            for the peak centers.

            From the refitted peaks the positions of the detectors in the
            tube are recalculated.

            @param ws: the workspace to get the tube geometry from
            @param calibrationTable: the calibration table output from running calibration
            @param peaksTable: the table containing the fitted peak centers from calibration
            @param spec: the tube spec for the instrument
            @param idealTube: the ideal tube for the instrument
            @param fitPar: the fitting parameters for calibration
            @param threshold: tolerance defining is a peak is outside of the acceptable range
            @return table of corrected detector positions
            """
            table_name = calibrationTable.name() + 'Corrected'
            corrections_table = mantid.CreateEmptyTableWorkspace(OutputWorkspace=table_name)
            corrections_table.addColumn('int', "Detector ID")
            corrections_table.addColumn('V3D', "Detector Position")

            mean_peaks, bad_tubes = findBadPeakFits(peaksTable, threshold)

            for index in bad_tubes:
                print("Refitting tube %s" % spec.getTubeName(index))
                tube_dets, _ = spec.getTube(index)
                getPoints(ws, idealTube.getFunctionalForms(), fitPar, tube_dets)
                tube_ws = mantid.mtd['TubePlot']
                fit_ws = mantid.FindPeaks(InputWorkspace=tube_ws, WorkspaceIndex=0,
                                          PeakPositions=fitPar.getPeaks(), PeaksList='RefittedPeaks')
                centers = [row['centre'] for row in fit_ws]
                detIDList, detPosList = getCalibratedPixelPositions(ws, centers, idealTube.getArray(), tube_dets)

                for id, pos in zip(detIDList, detPosList):
                    corrections_table.addRow({'Detector ID': id, 'Detector Position': kernel.V3D(*pos)})

            return corrections_table

        corrected_calibration_table = correctMisalignedTubes(ws, calibrationTable, peaks, spec, idealTube, fitPar)
        self.correction_table = corrected_calibration_table
        tube.saveCalibration(self.correction_table.getName(), out_path=self.calibration_out_path)
        tube.saveCalibration(self.calibration_table.getName(), out_path=self.correction_out_path)
Example #29
0
def calibrateMerlin(filename):
  # == Set parameters for calibration ==

    rangeLower = 3000 # Integrate counts in each spectra from rangeLower to rangeUpper
    rangeUpper = 20000 #

  # Get calibration raw file and integrate it
    rawCalibInstWS = LoadRaw(filename)    #'raw' in 'rawCalibInstWS' means unintegrated.
    print "Integrating Workspace"
    CalibInstWS = Integration( rawCalibInstWS, RangeLower=rangeLower, RangeUpper=rangeUpper )
    DeleteWorkspace(rawCalibInstWS)
    print "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate"

  # the known positions are given in pixels inside the tubes and transformed to provide the positions
  # with the center of the tube as the origin
    knownPositions = 2.92713867188*(numpy.array([ 27.30074322, 92.5,    294.65178585,    362.37861919 , 512.77103043    ,663.41425323, 798.3223896,     930.9, 997.08480835])/1024 - 0.5)
    funcForm = numpy.array([2,2,1,1,1,1,1,2,2],numpy.int8)
  # The calibration will follow different steps for sets of tubes

  # For the door9, the best points to define the known positions are the 1st edge, 5 peaks, last edge.
    points7 = knownPositions[[0,2,3,4,5,6,8]]
    points7func = funcForm[[0,2,3,4,5,6,8]]

    door9pos = points7
    door9func = points7func
    CalibratedComponent = 'MERLIN/door9'    # door9
  # == Get the calibration and put results into calibration table ==
  # also put peaks into PeakFile
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, door9pos, door9func,
        outputPeak=True,
        margin=30,
        rangeList=range(20) # because 20, 21, 22, 23 are defective detectors
        )
    print "Got calibration (new positions of detectors) and put slit peaks into file TubeDemoMerlin01.txt"
    analisePeakTable(peakTable, 'door9_tube1_peaks')

  # For the door8, the best points to define the known positions are the 1st edge, 5 peaks, last_edge
    door8pos = points7
    door8func = points7func
    CalibratedComponent = 'MERLIN/door8'
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, door8pos,
        door8func,
    outputPeak = True, #change to peakTable to append to peakTable
    calibTable = calibrationTable,
    margin = 30)
    analisePeakTable(peakTable, 'door8_peaks')

  # For the doors 7,6,5,4, 2, 1 we may use the 9 points
    doorpos = knownPositions
    doorfunc = funcForm
    CalibratedComponent = ['MERLIN/door%d'%(i) for i in [7,6,5,4, 2, 1]]
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos,\
        doorfunc,\
    outputPeak = True,\
    calibTable = calibrationTable,\
    margin = 30)
    analisePeakTable(peakTable, 'door1to7_peaks')

  # The door 3 is a special case, because it is composed by diffent kind of tubes.
  # door 3 tubes: 5_8, 5_7, 5_6, 5_5, 5_4, 5_3, 5_2, 5_1, 4_8, 4_7, 4_6, 4_5, 4_4, 4_3, 4_2, 4_1, 3_8, 3_7, 3_6, 3_5, 3_4
  # obeys the same rules as the doors 7, 6, 5, 4, 2, 1
  # For the tubes 3_3, 3_2, 3_1 -> it is better to skip the central peak
  # For the tubes 1_x (smaller tube below), it is better to take the final part of known positions: peak4,peak5,edge6,edge7
  # For the tubes 2_x (smaller tube above, it is better to take the first part of known positions: edge1, edge2, peak1,peak2

  # NOTE: the smaller tubes they have length = 1.22879882813, but 1024 detectors
  # so we have to correct the known positiosn by multiplying by its lenght and dividing by the longer dimension

    from tube_calib_fit_params import TubeCalibFitParams

  # calibrating tubes 1_x
    CalibratedComponent = ['MERLIN/door3/tube_1_%d'%(i) for i in range(1,9)]

    half_diff_center = (2.92713867188 -1.22879882813)/2    # difference among the expected center position for both tubes

  # here a little bit of attempts is necessary. The efective center position and lengh is different for the calibrated tube, that
  # is the reason, the calibrated values of the smaller tube does not seems aligned with the others. By, finding the 'best' half_diff_center
  # value, the alignment occurs nicely.
    half_diff_center = 0.835 #

  # the knownpositions were given with the center of the bigger tube as origin, to convert
  # to the center of the upper tube as origin is necessary to subtract them with  the half_diff_center
    doorpos = knownPositions[[5,6,7,8]] - half_diff_center
    doorfunc = [1,1,2,2]
  # for the smal tubes, automatically searching for the peak position in pixel was not working quite well,
  # so we will give the aproximate position for these tubes through fitPar argument
    fitPar = TubeCalibFitParams([216, 527, 826, 989])
    fitPar.setAutomatic(True)

    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos,\
    doorfunc,\
    outputPeak = True,\
    fitPar = fitPar,\
    calibTable = calibrationTable,\
    margin = 30)
    analisePeakTable(peakTable, 'door3_tube1_peaks')

  # calibrating tubes 2_x
    CalibratedComponent = ['MERLIN/door3/tube_2_%d'%(i) for i in range(1,9)]
  # the knownpositions were given with the center of the bigger tube as origin, to convert
  # to the center of the lower tube as origin is necessary to sum them with  (len_big - len_small)/2
    doorpos = knownPositions[[0,1,2,3]] + half_diff_center
  # print doorpos
    doorfunc = [2,2,1,1]

  # for the smal tubes, automatically searching for the peak position in pixel was not working quite well,
  # so we will give the aproximate position for these tubes through fitPar argument
    fitPar = TubeCalibFitParams([50, 202, 664, 815])
    fitPar.setAutomatic(True)

    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos,\
    doorfunc,\
    outputPeak = True,\
    calibTable = calibrationTable,\
    fitPar = fitPar,\
    margin = 30)

    analisePeakTable(peakTable, 'door3_tube2_peaks')


  # calibrating tubes 3_3,3_2,3_1
    CalibratedComponent = ['MERLIN/door3/tube_3_%d'%(i) for i in [1,2,3]]
    doorpos = knownPositions[[0,1,2,3,5,6,7,8]]
    doorfunc = funcForm[[0,1,2,3,5,6,7,8]]
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos,\
    doorfunc,\
    outputPeak = True,\
    calibTable = calibrationTable,\
    margin = 30)
    analisePeakTable(peakTable, 'door3_123_peaks')

  # calibrating others inside door3
  # 5_8, 5_7, 5_6, 5_5, 5_4, 5_3, 5_2, 5_1, 4_8, 4_7, 4_6, 4_5, 4_4, 4_3, 4_2, 4_1, 3_8, 3_7, 3_6, 3_5, 3_4
    part_3 = ['MERLIN/door3/tube_3_%d'%(i) for i in [4,5,6,7,8]]
    part_4 = ['MERLIN/door3/tube_4_%d'%(i) for i in range(1,9)]
    part_5 = ['MERLIN/door3/tube_5_%d'%(i) for i in range(1,9)]
    CalibratedComponent = part_3 + part_4 + part_5
    doorpos = knownPositions
    doorfunc = funcForm
    calibrationTable, peakTable = tube.calibrate(CalibInstWS, CalibratedComponent, doorpos,\
        doorfunc,\
    outputPeak = True,\
    calibTable = calibrationTable,\
    margin = 30)
    analisePeakTable(peakTable, 'door3_peaks')

  # == Apply the Calibation ==
    ApplyCalibration( Workspace=CalibInstWS, PositionTable=calibrationTable)
    print "Applied calibration"
# == Create Objects needed for calibration ==

# Specify components to calibrate
thisTubeSet = TubeSpec(CalibInstWS)
thisTubeSet.setTubeSpecByString(CalibratedComponent1)
thisTubeSet.setTubeSpecByString(CalibratedComponent2)

# Specify the known positions
knownPos = [-0.50, -0.16, -0.00, 0.16, 0.50]
funcForm = [2, 1, 1, 1, 2]

print("Created objects needed for calibration.")

# == Get the calibration and put results into calibration table ==

calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                             thisTubeSet,
                                             knownPos,
                                             funcForm,
                                             outputPeak=True)
print("Got calibration (new positions of detectors) ")

# == Apply the Calibation ==
mantid.ApplyCalibration(Workspace=CalibInstWS,
                        CalibrationTable=calibrationTable)
print("Applied calibration")

# == Save workspace ==
# mantid.SaveNexusProcessed(CalibInstWS, path+'TubeCalibDemoMapsResult.nxs', "Result of Running TCDemoMaps.py")
# print("saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs")
Example #31
0
def CalibrateMerlin(RunNumber):
    # == Set parameters for calibration ==
    previousDefaultInstrument = mantid.config['default.instrument']
    mantid.config['default.instrument'] = "MERLIN"
    filename = str(RunNumber)  # Name of calibration run.
    rangeLower = 3000  # Integrate counts in each spectra from rangeLower to rangeUpper
    rangeUpper = 20000  #

    # Set parameters for ideal tube.
    Left = 2.0  # Where the left end of tube should be in pixels (target for AP)
    Centre = 512.5  # Where the centre of the tube should be in pixels (target for CP)
    Right = 1023.0  # Where the right of the tube should be in pixels (target for BP)
    ActiveLength = 2.9  # Active length of tube in Metres

    # Set initial parameters for peak finding
    ExpectedHeight = 1000.0  # Expected Height of Gaussian Peaks (initial value of fit parameter)
    ExpectedWidth = 32.0  # Expected width of centre peak in Pixels (initial value of fit parameter)
    ExpectedPositions = [
        35.0, 512.0, 989.0
    ]  # Expected positions of the edges and peak in pixels (initial values of fit parameters)

    # Set what we want to calibrate (e.g whole instrument or one door )
    CalibratedComponent = 'MERLIN'  # Calibrate door 2

    # Get calibration raw file and integrate it
    print(filename)
    rawCalibInstWS = mantid.LoadRaw(filename)
    # 'raw' in 'rawCalibInstWS' means unintegrated.
    print("Integrating Workspace")
    CalibInstWS = mantid.Integration(rawCalibInstWS,
                                     RangeLower=rangeLower,
                                     RangeUpper=rangeUpper)
    mantid.DeleteWorkspace(rawCalibInstWS)
    print(
        "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate"
    )

    # == Create Objects needed for calibration ==

    ## In the merlin case, the positions are usually given in pixels, instead of being given in
    ## meters, to convert to meter and put the origin in the center, we have to apply the following
    ## transformation:
    ##
    ## pos = pixel * length/npixels - length/2 = length (pixel/npixels - 1/2)
    ##
    ## for merlin: npixels = 1024

    knownPos = ActiveLength * (numpy.array([Left, Centre, Right]) / 1024.0 -
                               0.5)
    funcForm = 3 * [1]

    # Get fitting parameters
    fitPar = TubeCalibFitParams(ExpectedPositions,
                                ExpectedHeight,
                                ExpectedWidth,
                                margin=40)

    print("Created objects needed for calibration.")

    # == Get the calibration and put results into calibration table ==
    # also put peaks into PeakFile
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 knownPos,
                                                 funcForm,
                                                 outputPeak=True,
                                                 fitPar=fitPar,
                                                 plotTube=list(
                                                     range(0, 280, 20)))
    print(
        "Got calibration (new positions of detectors) and put slit peaks into file TubeDemoMerlin01.txt"
    )

    # == Apply the Calibation ==
    mantid.ApplyCalibration(Workspace=CalibInstWS,
                            CalibrationTable=calibrationTable)
    print("Applied calibration")

    # == Save workspace ==
    # mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoMerlinResult.nxs', "Result of Running TubeCalibDemoMerlin_Simple.py")
    # print("saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMerlinResult.nxs")

    # == Reset default instrument ==
    mantid.config['default.instrument'] = previousDefaultInstrument
Example #32
0
funcForm = [2, 1, 1, 1, 2]

# Get fitting parameters
# Set initial parameters for peak finding
ExpectedHeight = -1000.0  # Expected Height of Gaussian Peaks (initial value of fit parameter)
ExpectedWidth = 8.0  # Expected width of Gaussian peaks in pixels  (initial value of fit parameter)
ExpectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0
                     ]  # Expected positions of the edges and Gaussian peaks
# in pixels (initial values of fit parameters)
fitPar = TubeCalibFitParams(ExpectedPositions, ExpectedHeight, ExpectedWidth)
fitPar.setAutomatic(True)

print("Created objects needed for calibration.")

# == Get the calibration and put results into calibration table ==
calibrationTable = tube.calibrate(CalibInstWS,
                                  CalibratedComponent,
                                  knownPos,
                                  funcForm,
                                  fitPar=fitPar)
print("Got calibration (new positions of detectors) ")

# == Apply the Calibation ==
mantid.ApplyCalibration(Workspace=CalibInstWS,
                        CalibrationTable=calibrationTable)
print("Applied calibration")

# == Save workspace ==
# mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoMapsResult.nxs', "Result of Running TCDemoMaps.py")
# print("saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs")
Example #33
0
def improvingCalibrationSingleTube(filename):
    """
    The :func:`~Examples.provideTheExpectedValue` provided a good solution, but there are few
    tubes whose calibration was not so good.

    This method explores how to deal with these tubes.

    First of all, it is important to identify the tubes that did not work well.

    From the outputs of provideTheExpectedValue, looking inside the instrument tree,
    it is possible to list all the tubes that are not so good.

    Unfortunatelly, they do not have a single name identifier.
    So, locating them it is a little bit trickier.
    The :func:`~Examples.findThoseTubesThatNeedSpecialCareForCalibration` shows one way of finding those
    tubes.     The index is the position inside the PeakTable.

    For this example, we have used inspection from the Instrument View.
    One of them is inside the A1_Window, 3rd PSD_TUBE_STRIP 8 pack up, 4th PSD_TUBE_STRIP: Index = 8+8+4 - 1 = 19.

    In this example, we will ask the calibration to run the calibration only for 3 tubes
    (indexes 18,19,20). Them, we will check why the 19 is not working well. Finally, we will try to
    provide another peaks position for this tube,
    and run the calibration again for these tubes, to improve the results.

    This example shows how to use **overridePeaks** option
    """
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 knownPos,
                                                 funcFactor,
                                                 fitPar=fitPar,
                                                 outputPeak=True,
                                                 plotTube=[18, 19, 20],
                                                 rangeList=[18, 19, 20])

    ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)

    # reload to reset the calibration applied
    CalibInstWS = loadingStep(filename)
    # looking into the second line of calibrationTable, you will see that it defines the peaks for the first position
    # as 14.9788, -0.303511, 9.74828
    # let's change the peak from  -0.303511 to 8.14

    #to override the peaks definition, we use the overridePeaks
    overridePeaks = {19: [8.14, 80.9771, 123.221, 164.993, 245.717]}

    # == Get the calibration and put results into calibration table ==
    # we will not plot anymore, because it will not plot the overrided peaks
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 knownPos,
                                                 funcFactor,
                                                 fitPar=fitPar,
                                                 outputPeak=True,
                                                 rangeList=[18, 19, 20],
                                                 overridePeaks=overridePeaks)

    ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
def calibrateMerlin(filename):
    # == Set parameters for calibration ==

    rangeLower = 3000  # Integrate counts in each spectra from rangeLower to rangeUpper
    rangeUpper = 20000  #

    # Get calibration raw file and integrate it
    rawCalibInstWS = mantid.LoadRaw(
        filename)  # 'raw' in 'rawCalibInstWS' means unintegrated.
    print("Integrating Workspace")
    CalibInstWS = mantid.Integration(rawCalibInstWS,
                                     RangeLower=rangeLower,
                                     RangeUpper=rangeUpper)
    mantid.DeleteWorkspace(rawCalibInstWS)
    print(
        "Created workspace (CalibInstWS) with integrated data from run and instrument to calibrate"
    )

    # the known positions are given in pixels inside the tubes and transformed to provide the positions
    # with the center of the tube as the origin
    knownPositions = 2.92713867188 * (numpy.array([
        27.30074322, 92.5, 294.65178585, 362.37861919, 512.77103043,
        663.41425323, 798.3223896, 930.9, 997.08480835
    ]) / 1024 - 0.5)
    funcForm = numpy.array([2, 2, 1, 1, 1, 1, 1, 2, 2], numpy.int8)
    # The calibration will follow different steps for sets of tubes

    # For the door9, the best points to define the known positions are the 1st edge, 5 peaks, last edge.
    points7 = knownPositions[[0, 2, 3, 4, 5, 6, 8]]
    points7func = funcForm[[0, 2, 3, 4, 5, 6, 8]]

    door9pos = points7
    door9func = points7func
    CalibratedComponent = 'MERLIN/door9'  # door9
    # == Get the calibration and put results into calibration table ==
    # also put peaks into PeakFile
    calibrationTable, peakTable = tube.calibrate(
        CalibInstWS,
        CalibratedComponent,
        door9pos,
        door9func,
        outputPeak=True,
        margin=30,
        rangeList=list(range(20))
        # because 20, 21, 22, 23 are defective detectors
    )
    print(
        "Got calibration (new positions of detectors) and put slit peaks into file TubeDemoMerlin01.txt"
    )
    analisePeakTable(peakTable, 'door9_tube1_peaks')

    # For the door8, the best points to define the known positions are the 1st edge, 5 peaks, last_edge
    door8pos = points7
    door8func = points7func
    CalibratedComponent = 'MERLIN/door8'
    calibrationTable, peakTable = tube.calibrate(
        CalibInstWS,
        CalibratedComponent,
        door8pos,
        door8func,
        outputPeak=True,  # change to peakTable to append to peakTable
        calibTable=calibrationTable,
        margin=30)
    analisePeakTable(peakTable, 'door8_peaks')

    # For the doors 7,6,5,4, 2, 1 we may use the 9 points
    doorpos = knownPositions
    doorfunc = funcForm
    CalibratedComponent = ['MERLIN/door%d' % (i) for i in [7, 6, 5, 4, 2, 1]]
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 doorpos,
                                                 doorfunc,
                                                 outputPeak=True,
                                                 calibTable=calibrationTable,
                                                 margin=30)
    analisePeakTable(peakTable, 'door1to7_peaks')

    # The door 3 is a special case, because it is composed by diffent kind of tubes.
    # door 3 tubes: 5_8, 5_7, 5_6, 5_5, 5_4, 5_3, 5_2, 5_1, 4_8, 4_7, 4_6, 4_5, 4_4, 4_3, 4_2, 4_1, 3_8, 3_7, 3_6, 3_5, 3_4
    # obeys the same rules as the doors 7, 6, 5, 4, 2, 1
    # For the tubes 3_3, 3_2, 3_1 -> it is better to skip the central peak
    # For the tubes 1_x (smaller tube below), it is better to take the final part of known positions: peak4,peak5,edge6,edge7
    # For the tubes 2_x (smaller tube above, it is better to take the first part of known positions: edge1, edge2, peak1,peak2

    # NOTE: the smaller tubes they have length = 1.22879882813, but 1024 detectors
    # so we have to correct the known positiosn by multiplying by its lenght and dividing by the longer dimension

    from tube_calib_fit_params import TubeCalibFitParams

    # calibrating tubes 1_x
    CalibratedComponent = ['MERLIN/door3/tube_1_%d' % (i) for i in range(1, 9)]

    half_diff_center = (
        2.92713867188 -
        1.22879882813) / 2  # difference among the expected center position for
    # both tubes here a little bit of attempts is necessary.
    # The effective center position and lengh is different for the calibrated tube, that is the reason,
    # the calibrated values of the smaller tube does not seems aligned with the others. By, finding the
    # 'best' half_diff_center value, the alignment occurs nicely.
    half_diff_center = 0.835  #

    # the knownpositions were given with the center of the bigger tube as origin, to convert
    # to the center of the upper tube as origin is necessary to subtract them with  the half_diff_center
    doorpos = knownPositions[[5, 6, 7, 8]] - half_diff_center
    doorfunc = [1, 1, 2, 2]
    # for the smal tubes, automatically searching for the peak position in pixel was not working quite well,
    # so we will give the aproximate position for these tubes through fitPar argument
    fitPar = TubeCalibFitParams([216, 527, 826, 989])
    fitPar.setAutomatic(True)

    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 doorpos,
                                                 doorfunc,
                                                 outputPeak=True,
                                                 fitPar=fitPar,
                                                 calibTable=calibrationTable,
                                                 margin=30)
    analisePeakTable(peakTable, 'door3_tube1_peaks')

    # calibrating tubes 2_x
    CalibratedComponent = ['MERLIN/door3/tube_2_%d' % (i) for i in range(1, 9)]
    # the knownpositions were given with the center of the bigger tube as origin, to convert
    # to the center of the lower tube as origin is necessary to sum them with  (len_big - len_small)/2
    doorpos = knownPositions[[0, 1, 2, 3]] + half_diff_center
    # print doorpos
    doorfunc = [2, 2, 1, 1]

    # for the smal tubes, automatically searching for the peak position in pixel was not working quite well,
    # so we will give the aproximate position for these tubes through fitPar argument
    fitPar = TubeCalibFitParams([50, 202, 664, 815])
    fitPar.setAutomatic(True)

    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 doorpos,
                                                 doorfunc,
                                                 outputPeak=True,
                                                 calibTable=calibrationTable,
                                                 fitPar=fitPar,
                                                 margin=30)

    analisePeakTable(peakTable, 'door3_tube2_peaks')

    # calibrating tubes 3_3,3_2,3_1
    CalibratedComponent = ['MERLIN/door3/tube_3_%d' % (i) for i in [1, 2, 3]]
    doorpos = knownPositions[[0, 1, 2, 3, 5, 6, 7, 8]]
    doorfunc = funcForm[[0, 1, 2, 3, 5, 6, 7, 8]]
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 doorpos,
                                                 doorfunc,
                                                 outputPeak=True,
                                                 calibTable=calibrationTable,
                                                 margin=30)
    analisePeakTable(peakTable, 'door3_123_peaks')

    # calibrating others inside door3
    # 5_8, 5_7, 5_6, 5_5, 5_4, 5_3, 5_2, 5_1, 4_8, 4_7, 4_6, 4_5, 4_4, 4_3, 4_2, 4_1, 3_8, 3_7, 3_6, 3_5, 3_4
    part_3 = ['MERLIN/door3/tube_3_%d' % (i) for i in [4, 5, 6, 7, 8]]
    part_4 = ['MERLIN/door3/tube_4_%d' % (i) for i in range(1, 9)]
    part_5 = ['MERLIN/door3/tube_5_%d' % (i) for i in range(1, 9)]
    CalibratedComponent = part_3 + part_4 + part_5
    doorpos = knownPositions
    doorfunc = funcForm
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 doorpos,
                                                 doorfunc,
                                                 outputPeak=True,
                                                 calibTable=calibrationTable,
                                                 margin=30)
    analisePeakTable(peakTable, 'door3_peaks')

    # == Apply the Calibation ==
    mantid.ApplyCalibration(Workspace=CalibInstWS,
                            PositionTable=calibrationTable)
    print("Applied calibration")
Example #35
0
def findThoseTubesThatNeedSpecialCareForCalibration(filename):
    """
    The example :func:`provideTheExpectedValue` has shown its capability to calibrate almost
    all tubes, but,    as explored in the :func:`improvingCalibrationOfListOfTubes` and
    :func:`improvingCalibrationSingleTube` there are
    some tubes that could not be calibrated using that method.

    The goal of this method is to show one way to find the tubes that will require special care.

    It will first perform the same calibration seen in :func:`provideTheExpectedValue`,
    them, it will process the **peakTable** output of the calibrate method when enabling the
    parameter **outputPeak**.

    It them creates the Peaks workspace, that is the diffence of the peaks position from the
    expected values of the peaks positions for all the tubes. This allows to spot what are the
    tubes whose fitting are outliers in relation to the others.

    .. image:: /images/plotingPeaksDifference.png

    The final result for this method is to output using **plotTube** the result of the fitting
    to all the 'outliers' tubes.
    """
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)
    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all
    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # == Get the calibration and put results into calibration table ==
    calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                                 CalibratedComponent,
                                                 knownPos,
                                                 funcFactor,
                                                 fitPar=fitPar,
                                                 outputPeak=True)

    # == now, lets investigate the peaks

    #parsing the peakTable to produce a numpy array with dimension (number_of_tubes x number_of_peaks)
    print 'parsing the peak table'
    n = len(peakTable)
    peaksId = n * ['']
    data = numpy.zeros((n, 5))
    line = 0
    for row in peakTable:
        data_row = [row['Peak%d' % (i)] for i in [1, 2, 3, 4, 5]]
        data[line, :] = data_row
        peaksId[line] = row['TubeId']
        line += 1
    # data now has all the peaks positions for each tube
    # the mean value is the expected value for the peak position for each tube
    expected_peak_pos = numpy.mean(data, axis=0)
    #calculate how far from the expected position each peak position is
    distance_from_expected = numpy.abs(data - expected_peak_pos)

    print 'Creating the Peaks Workspace that shows the distance from the expected value for all peaks for each tube'
    # Let's see these peaks:
    CreateWorkspace(range(n),
                    distance_from_expected,
                    NSpec=5,
                    OutputWorkspace='Peaks')

    # plot all the 5 peaks for Peaks Workspace. You will see that most of the tubes differ
    # at most 12 pixels from the expected values.

    #so let's investigate those that differ more than 12
    # return an array with the indexes for the first axis which is the tube indentification
    check = numpy.where(distance_from_expected > 12)[0]

    #remove repeated values
    #select only those tubes inside the problematic_tubes
    problematic_tubes = list(set(check))

    print 'Tubes whose distance is far from the expected value: ', problematic_tubes

    print 'Calibrating again only these tubes'
    #let's confir that our suspect works
    CalibInstWS = loadingStep(filename)
    tube.calibrate(CalibInstWS,
                   CalibratedComponent,
                   knownPos,
                   funcFactor,
                   fitPar=fitPar,
                   rangeList=problematic_tubes,
                   plotTube=problematic_tubes)
Example #36
0
# First array gives positions in Metres and second array gives type 1=Gaussian peak 2=edge.
# See http://www.mantidproject.org/IdealTube for details.
knownPos = [-0.50, -0.165, -0.00, 0.165, 0.50]
funcForm = [2, 1, 1, 1, 2]

# Get fitting parameters
fitPar = TubeCalibFitParams(ExpectedPositions, ExpectedHeight, ExpectedWidth)
fitPar.setAutomatic(True)

print("Created objects needed for calibration.")

# == Get the calibration and put results into calibration table ==
# also put peaks into PeakFile
calibrationTable, peakTable = tube.calibrate(CalibInstWS,
                                             CalibratedComponent,
                                             knownPos,
                                             funcForm,
                                             fitPar=fitPar,
                                             outputPeak=True)
print("Got calibration (new positions of detectors) ")

# == Apply the Calibation ==
mantid.ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)
print("Applied calibration")

# == Save workspace ==
mantid.SaveNexusProcessed(CalibInstWS, 'TubeCalibDemoMapsResult.nxs',
                          "Result of Running TCDemoMaps_B1.py")
print(
    "saved calibrated workspace (CalibInstWS) into Nexus file TubeCalibDemoMapsResult.nxs"
)
Example #37
0
def completeCalibration(filename):
    """
    This example shows how to use some properties of calibrate method to
    join together the calibration done in :func:`provideTheExpectedValue`,
    and improved in :func:`calibrateB2Window`, and :func:`improvingCalibrationOfListOfTubes`.

    It also improves the result of the calibration because it deals with the E door. The
    aquired data cannot be used to calibrate the E door, and trying to do so, produces a bad
    result. In this example, the tubes inside the E door are excluded to the calibration.
    Using the '''rangeList''' option.
    """

    # first step, load the workspace
    from tube_calib_fit_params import TubeCalibFitParams
    CalibInstWS = loadingStep(filename)

    # == Set parameters for calibration ==
    # Set what we want to calibrate (e.g whole intrument or one door )
    CalibratedComponent = 'MAPS'  # Calibrate all

    # define the known positions and function factor (edge, peak, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, -0.00, 0.16, 0.50], [2, 1, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 128.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    #execute the improvingCalibrationOfListOfTubes excluding the range of b2 window
    # correct the definition of the peaks for the folowing indexes
    #define_peaks = {19:[10, 80.9771, 123.221, 164.993, 245.717], # the first one was bad
    #	37: [6.36, 80.9347, 122.941, 165.104, 248.32], # the first one was bad
    #	71: [8.62752, 85.074, 124.919, 164.116, 246.82 ], # the last one was bad - check if we can inprove
    #	75: [14.4285, 90.087, 128.987, 167.047, 242.62], # the last one was bad - check if we can inprove
    #	181: [11.726, 94.0496, 137.816,  180, 255], # the third peak was lost
    #	186:[11.9382, 71.5203, 107, 147.727, 239.041], #lost the second peak
    #	234: [4.84, 82.7824, 123.125, 163.945, 241.877], # the first one was bad
    #	235: [4.84, 80.0077, 121.002, 161.098, 238.502], # the first one was bad
    #	245: [9.88089, 93.0593, 136.911, 179.5, 255], # the third peak was bad
    #	273: [18.3711, 105.5, 145.5, 181.6, 243.252],# lost first and third peaks
    #	345: [4.6084, 87.0351, 128.125, 169.923, 245.3]} # the last one was bad
    define_peaks = {
        19: [10, 80.9771, 123.221, 164.993, 245.717],
        37: [6.36, 80.9347, 122.941, 165.104, 248.32],
        71: [8.62752, 85.074, 124.919, 164.116, 246.82],
        75: [14.4285, 90.087, 128.987, 167.047, 242.62],
        181: [11.726, 94.0496, 137.816, 180, 255],
        186: [11.9382, 71.5203, 107, 147.727, 239.041],
        234: [4.84, 82.7824, 123.125, 163.945, 241.877],
        235: [4.84, 80.0077, 121.002, 161.098, 238.502],
        245: [9.88089, 93.0593, 136.911, 179.5, 255],
        273: [18.3711, 105.5, 145.5, 181.6, 243.252],
        345: [4.6084, 87.0351, 128.125, 169.923, 245.3]
    }

    b2_window = range(196, 212) + range(222, 233)

    complete_range = range(648)

    # this data can not be used to calibrate the E1 window, so, let's remove it.
    e1_window = range(560, 577)
    aux = numpy.setdiff1d(complete_range, b2_window)
    # the group that have 3 stripts are all the tubes except the b2 window and e window.
    range_3_strips = numpy.setdiff1d(aux, e1_window)

    calibrationTable, peak3Table = tube.calibrate(CalibInstWS,
                                                  CalibratedComponent,
                                                  knownPos,
                                                  funcFactor,
                                                  fitPar=fitPar,
                                                  outputPeak=True,
                                                  overridePeaks=define_peaks,
                                                  rangeList=range_3_strips)

    # now calibrate the b2_window REMOVE SECOND PEAK
    # define the known positions and function factor (edge, peak, peak, edge)
    knownPos, funcFactor = [-0.50, -0.16, 0.16, 0.50], [2, 1, 1, 2]

    # the expected positions in pixels for the special points
    expectedPositions = [4.0, 85.0, 161.0, 252.0]
    fitPar = TubeCalibFitParams(expectedPositions)
    fitPar.setAutomatic(True)

    # apply the calibration for the b2_window 2 strips values
    calibrationTable, peak2Table = tube.calibrate(
        CalibInstWS,
        CalibratedComponent,
        knownPos,  #these parameters now have only 4 points
        funcFactor,
        fitPar=fitPar,
        outputPeak=True,
        calibTable=calibrationTable,  # it will append to the calibTable
        rangeList=b2_window)

    ApplyCalibration(Workspace=CalibInstWS, PositionTable=calibrationTable)