コード例 #1
0
def reduce(nxsfile,
           qaxis,
           outfile,
           use_ei_guess=False,
           ei_guess=None,
           eaxis=None,
           tof2E=True,
           ibnorm='ByCurrent'):
    """reduce a NeXus file to a I(Q,E) histogram using Mantid

    This is a wrapper of Mantid algorithms to reduce a NeXus file to IQE histogram.

    Parameters
    ----------

    nxsfile: str
        path to nxs file

    qaxis: 3-tuple of floats
        Momentum transfer axis. (Qmin, dQ, Qmax). unit: inverse angstrom

    outfile: str
        path to save nxs data

    use_ei_guess: boolean
        Use incident energy guess

    ei_guess: float
        Initial guess of incident energy (meV)

    eaxis: 3-tuple of floats
        Energy transfer axis. (Emin, dE, Emax). unit: meV

    tof2E: boolean
        Conversion from time of flight axis to energy axis or not.
        If the NeXus file is in time of flight, tof2E=True
        If the NeXus file is processed and in energy transfer, tof2E=False

    ibnorm: str
        Incident beam normalization choice. Allowed values: None, ByCurrent, ToMonitor
        For more details, see http://docs.mantidproject.org/nightly/algorithms/DgsReduction-v1.html
    """
    from mantid.simpleapi import DgsReduction, SaveNexus, Load
    from mantid import mtd
    import mantid.simpleapi as msa
    if tof2E == 'guess':
        # XXX: this is a simple guess. all raw data files seem to have root "entry"
        cmd = 'h5ls %s' % nxsfile
        import subprocess as sp, shlex
        o = sp.check_output(shlex.split(cmd)).strip().split()[0]
        tof2E = o == 'entry'
    if tof2E:
        if use_ei_guess:
            DgsReduction(
                SampleInputFile=nxsfile,
                IncidentEnergyGuess=ei_guess,
                UseIncidentEnergyGuess=use_ei_guess,
                OutputWorkspace='reduced',
                EnergyTransferRange=eaxis,
                IncidentBeamNormalisation=ibnorm,
            )
        else:
            DgsReduction(
                SampleInputFile=nxsfile,
                OutputWorkspace='reduced',
                EnergyTransferRange=eaxis,
                IncidentBeamNormalisation=ibnorm,
            )
        reduced = mtd['reduced']
    else:
        reduced = Load(nxsfile)

    # get eaxis info from mtd workspace, if necessary
    if eaxis is None:
        Edim = reduced.getXDimension()
        emin = Edim.getMinimum()
        emax = Edim.getMaximum()
        de = Edim.getX(1) - Edim.getX(0)
        eaxis = emin, de, emax
    qmin, dq, qmax = qaxis
    nq = int((qmax - qmin + dq / 2.) / dq)
    emin, de, emax = eaxis
    ne = int((emax - emin + de / 2.) / de)
    #
    md = msa.ConvertToMD(
        InputWorkspace=reduced,
        QDimensions='|Q|',
        dEAnalysisMode='Direct',
        MinValues="%s,%s" % (qmin, emin),
        MaxValues="%s,%s" % (qmax, emax),
    )
    binned = msa.BinMD(
        InputWorkspace=md,
        AxisAligned=1,
        AlignedDim0="|Q|,%s,%s,%s" % (qmin, qmax, nq),
        AlignedDim1="DeltaE,%s,%s,%s" % (emin, emax, ne),
    )
    # create histogram
    import histogram as H, histogram.hdf as hh
    data = binned.getSignalArray().copy()
    err2 = binned.getErrorSquaredArray().copy()
    nev = binned.getNumEventsArray()
    data /= nev
    err2 /= (nev * nev)
    import numpy as np
    qaxis = H.axis('Q',
                   boundaries=np.arange(qmin, qmax + dq / 2., dq),
                   unit='1./angstrom')
    eaxis = H.axis('E',
                   boundaries=np.arange(emin, emax + de / 2., de),
                   unit='meV')
    hist = H.histogram('IQE', (qaxis, eaxis), data=data, errors=err2)
    if outfile.endswith('.nxs'):
        import warnings
        warnings.warn(
            "reduce function no longer writes iqe.nxs nexus file. it only writes iqe.h5 histogram file"
        )
        outfile = outfile[:-4] + '.h5'
    hh.dump(hist, outfile)
    return hist
コード例 #2
0
ファイル: nxs.py プロジェクト: mcvine/instruments
def reduce(nxsfile,
           qaxis,
           outfile,
           use_ei_guess=False,
           ei_guess=None,
           eaxis=None,
           tof2E=True,
           ibnorm='ByCurrent'):
    from mantid.simpleapi import DgsReduction, SofQW3, SaveNexus, LoadInstrument, Load, MoveInstrumentComponent, \
        MaskBTP, ConvertToMD, BinMD, ConvertMDHistoToMatrixWorkspace, GetEiT0atSNS, GetEi
    from mantid import mtd
    ws = Load(nxsfile)

    if tof2E == 'guess':
        axis = ws.getAxis(0).getUnit().caption().lower()
        # axis name should be "Time-of-flight"
        tof2E = "time" in axis and "flight" in axis

    if tof2E:
        # mask packs around beam
        # MaskBTP(ws, Bank="98-102")
        if not use_ei_guess:
            run = ws.getRun()
            Efixed = run.getLogData('mcvine-Ei').value
            T0 = run.getLogData('mcvine-t0').value
        else:
            Efixed, T0 = ei_guess, 0

        DgsReduction(
            SampleInputWorkspace=ws,
            IncidentEnergyGuess=Efixed,
            UseIncidentEnergyGuess=True,
            TimeZeroGuess=T0,
            OutputWorkspace='reduced',
            EnergyTransferRange=eaxis,
            IncidentBeamNormalisation=ibnorm,
        )
        reduced = mtd['reduced']
    else:
        reduced = Load(nxsfile)

    # if eaxis is not specified, use the data in reduced workspace
    if eaxis is None:
        Edim = reduced.getXDimension()
        emin = Edim.getMinimum()
        emax = Edim.getMaximum()
        de = Edim.getX(1) - Edim.getX(0)
        eaxis = emin, de, emax

    qmin, dq, qmax = qaxis
    nq = int(round((qmax - qmin) / dq))
    emin, de, emax = eaxis
    ne = int(round((emax - emin) / de))
    md = ConvertToMD(
        InputWorkspace='reduced',
        QDimensions='|Q|',
        dEAnalysisMode='Direct',
        MinValues="%s,%s" % (qmin, emin),
        MaxValues="%s,%s" % (qmax, emax),
        SplitInto="%s,%s" % (nq, ne),
    )
    binned = BinMD(
        InputWorkspace=md,
        AxisAligned=1,
        AlignedDim0="|Q|,%s,%s,%s" % (qmin, qmax, nq),
        AlignedDim1="DeltaE,%s,%s,%s" % (emin, emax, ne),
    )
    # convert to histogram
    import histogram as H, histogram.hdf as hh
    data = binned.getSignalArray().copy()
    err2 = binned.getErrorSquaredArray().copy()
    nev = binned.getNumEventsArray()
    data /= nev
    err2 /= (nev * nev)
    qaxis = H.axis('Q',
                   boundaries=np.arange(qmin, qmax + dq / 2., dq),
                   unit='1./angstrom')
    eaxis = H.axis('E',
                   boundaries=np.arange(emin, emax + de / 2., de),
                   unit='meV')
    hist = H.histogram('IQE', (qaxis, eaxis), data=data, errors=err2)
    if outfile.endswith('.nxs'):
        import warnings
        warnings.warn(
            "reduce function no longer writes iqe.nxs nexus file. it only writes iqe.h5 histogram file"
        )
        outfile = outfile[:-4] + '.h5'
    hh.dump(hist, outfile)
    return