Beispiel #1
0
def get_nominal_difc(nxspath, idfpath, outpath=None):
    ws = msa.LoadEventNexus(nxspath, FilterByTimeStart=0, FilterByTimeStop=1)
    msa.LoadInstrument(ws, Filename=idfpath, RewriteSpectraMap=False)
    difc = msa.CalculateDIFC(InputWorkspace=ws)
    difc = difc.extractY().flatten().copy()
    msa.DeleteWorkspace('difc')
    if outpath:
        np.save(outpath, difc)
    return difc
Beispiel #2
0
 def cost(self, x):
     params0 = self.params0
     options = self.options
     params = opts2fullparams(x, params0, options)
     self.adjust_model(params)
     wks_name = self.comp_model.instrument_model.wks_name
     msa.CalculateDIFC(InputWorkspace=wks_name, OutputWorkspace='difc')
     difc_new = mtd['difc'].extractY().flatten()
     difc_new = np.ma.masked_array(difc_new, self.comp_model.instrument_model.mask)
     difc = self.difc
     return np.sum((difc_new-difc)**2)
Beispiel #3
0
def get_nominal_difc(nxspath, init_IDF, outdir):
    if not os.path.exists(outdir): os.makedirs(outdir)
    # ## Compute nominal difc
    ws = msa.LoadEventNexus(nxspath, FilterByTimeStart=0,
                            FilterByTimeStop=1)  # load just one second
    #
    msa.LoadInstrument(ws, Filename=init_IDF, RewriteSpectraMap=False)
    import shutil
    shutil.copyfile(init_IDF, os.path.join(outdir, 'init_IDF.xml'))
    #
    difc = msa.CalculateDIFC(InputWorkspace=ws)
    difc = difc.extractY().flatten().copy()
    msa.DeleteWorkspace('difc')
    np.save(os.path.join(outdir, 'difc-nominal.npy'), difc)
    return
    def _minimisation_func(self, x_0, wks_name, component, firstIndex,
                           lastIndex, difc, mask):
        """
        Basic minimization function used. Returns the chisquared difference between the expected
        difc and the new difc after the component has been moved or rotated.
        """
        xmap = self._mapOptions(x_0)

        if self._move:
            api.MoveInstrumentComponent(wks_name,
                                        component,
                                        X=xmap[0],
                                        Y=xmap[1],
                                        Z=xmap[2],
                                        RelativePosition=False)

        if self._rotate:
            (rotw, rotx, roty,
             rotz) = self._eulerToAngleAxis(xmap[3], xmap[4], xmap[5],
                                            self._eulerConvention)  # YZX
            api.RotateInstrumentComponent(wks_name,
                                          component,
                                          X=rotx,
                                          Y=roty,
                                          Z=rotz,
                                          Angle=rotw,
                                          RelativeRotation=False)

        api.CalculateDIFC(InputWorkspace=wks_name, OutputWorkspace=wks_name)

        difc_new = api.mtd[wks_name].extractY().flatten(
        )[firstIndex:lastIndex + 1]

        if self._masking:
            difc_new = np.ma.masked_array(difc_new, mask)

        return chisquare(f_obs=difc, f_exp=difc_new)[0]
Beispiel #5
0
 def difc(self):
     wks_name = self.wks_name
     msa.CalculateDIFC(InputWorkspace=wks_name, OutputWorkspace='difc')
     return mtd['difc'].extractY().flatten()
Beispiel #6
0
def get_I_d(nxs_files,
            init_IDF,
            outdir,
            packs,
            dt=1000.,
            d_axis=(2., 11., 0.02),
            Npixels_per_pack=1024):
    """nxs_files: paths of calibration nxs files
    init_IDF: initial IDF path
    outdir: output directory
    packs: list of pack names, e.g. C26B/eightpack-bottom
    dt: time step for loading files. too large will need too much memory
    d_axis: dmin, dmax, delta_d. e.g. 2., 11., 0.02
    Npixels_per_pack: number of pixels per pack

    Output files:
    * difc-nominal.npy
    * detIDs.npy
    * I_d-xbb.npy
    * I_d-y-PACKNAME.npy
    * pack-PACKNAME.yaml

    NOTE:
    * Assumed that the difc array from CalculateDIFC is ordered according to the "spectrrum list" in
      the mantid workspace. See function getDetIDs
    * Different combinations of nxs_files, init_IDF, d_axis should use different outdirs
    """
    if not os.path.exists(outdir): os.makedirs(outdir)
    # ## Compute nominal difc using first file in the list
    nxspath = nxs_files[0]
    ws = msa.LoadEventNexus(nxspath, FilterByTimeStart=0,
                            FilterByTimeStop=1)  # load just one second
    #
    msa.LoadInstrument(ws, Filename=init_IDF, RewriteSpectraMap=False)
    import shutil
    shutil.copyfile(init_IDF, os.path.join(outdir, 'init_IDF.xml'))
    #
    difc = msa.CalculateDIFC(InputWorkspace=ws)
    difc = difc.extractY().flatten().copy()
    msa.DeleteWorkspace('difc')
    np.save(os.path.join(outdir, 'difc-nominal.npy'), difc)
    # IDs of all pixels
    detIDs = getDetIDs(ws)
    np.save(os.path.join(outdir, 'detIDs.npy'), detIDs)
    #
    # map pack name to (start_pixelID, stop_pixelID)
    pack2pixelID_start_stop = dict()
    for name in packs:
        pack2pixelID_start_stop[name] = getFirstLastPixelIDs(ws, name)
        continue
    # clean up
    msa.DeleteWorkspace('ws')

    runtimes = dict()
    for f in nxs_files:
        runtimes[f] = getRunTime(f)
    print "* run times:", runtimes

    dmin, dmax, delta_d = d_axis
    Nd = int((dmax - dmin) / delta_d)
    print "* Number of d bins:", Nd

    #
    Npacks = len(packs)

    y_matrix = np.zeros((Npacks, Npixels_per_pack, Nd))
    xbb_saved = None
    for nxsfile in nxs_files:
        print "* Working on", nxsfile
        t_total = runtimes[nxsfile]
        for tstart in np.arange(0, t_total - dt, dt):
            print "* tstart", tstart
            tend = min(t_total - 1, tstart + dt)
            ws = msa.LoadEventNexus(nxsfile,
                                    FilterByTimeStart=tstart,
                                    FilterByTimeStop=tend)
            msa.LoadInstrument(ws, Filename=init_IDF, RewriteSpectraMap=False)
            I_d = msa.ConvertUnits(InputWorkspace=ws,
                                   Target='dSpacing',
                                   EMode='Elastic')
            I_d = msa.Rebin(InputWorkspace=I_d,
                            Params='%s,%s,%s' % (dmin, delta_d, dmax))

            # loop over packs
            for ipack, packname in enumerate(packs):
                firstpixel, lastpixel = pack2pixelID_start_stop[packname]
                startindex = detIDs.index(firstpixel)
                endindex = detIDs.index(lastpixel)
                print "array indexes of first and last pixel", startindex, endindex

                y_pack = y_matrix[ipack]
                # loop over pixels in the pack
                for i, pixelindex in enumerate(range(startindex,
                                                     endindex + 1)):
                    I_d_pixel = msa.SumSpectra(InputWorkspace=I_d,
                                               StartWorkspaceIndex=pixelindex,
                                               EndWorkspaceIndex=pixelindex)
                    xbb = I_d_pixel.readX(0)
                    if xbb_saved is None: xbb_saved = np.array(xbb, copy=True)
                    y = I_d_pixel.readY(0)
                    y_pack[i] += y
                    msa.DeleteWorkspace('I_d_pixel')
                    continue
                continue

            msa.DeleteWorkspaces(['ws', 'I_d'])
            continue
        continue

    xbb = np.arange(dmin, dmax + delta_d / 2., delta_d)
    np.save(os.path.join(outdir, "I_d-xbb.npy"), xbb)
    # for debugging
    np.save(os.path.join(outdir, "I_d-y_matrix.npy"), y_matrix)

    for ipack, packname in enumerate(packs):
        y_pack = y_matrix[ipack]
        packname1 = packname.split('/')[0]  # "C25T"
        # save y values of I(d) for the pack
        np.save(os.path.join(outdir, "I_d-y-%s.npy" % packname1), y_pack)
        # save pack info
        first, last = pack2pixelID_start_stop[packname]
        pixelIDs = dict(first=first, last=last)
        pack_info = dict(pixelIDs=pixelIDs)
        dumpYaml(pack_info, os.path.join(outdir, 'pack-%s.yaml' % packname1))
        continue
    return
# coding: utf-8

import os, numpy as np
from mantid import simpleapi as msa, mtd

workdir = "/SNS/users/lj7/dv/sns-chops/detcalib/SEQ"
os.chdir(workdir)

# ## Compute nominal difc
nxspath = '/SNS/SEQ/IPTS-19573/nexus/SEQ_130249.nxs.h5'
ws = msa.LoadEventNexus(nxspath, FilterByTimeStart=0, FilterByTimeStop=1)
msa.LoadInstrument(ws,
                   Filename='./SEQUOIA_Definition_guessshortpacks.xml',
                   RewriteSpectraMap=False)
difc = msa.CalculateDIFC(InputWorkspace=ws)
difc = difc.extractY().flatten().copy()
msa.DeleteWorkspace('difc')

# get det ID list
detIDs = []
for i in range(ws.getNumberHistograms()):
    sp = ws.getSpectrum(i)
    dets = list(sp.getDetectorIDs())
    assert len(dets) == 1
    detIDs.append(dets[0])
    continue
for i in range(len(detIDs) - 1):
    assert detIDs[i] < detIDs[i + 1]


# # Get pack index
Beispiel #8
0
    def _minimisation_func(self, x_0, wks_name, component, firstIndex,
                           lastIndex):
        """
        Basic minimization function used. Returns the sum of the absolute values for the fractional peak
        deviations:

        .. math::

            \\sum_i^{N_d}\\sum_j^{N_p} (1 - m_{i,j}) \\frac{|d_{i,j} - d_j^*|}{d_j^*}

        where :math:`N_d` is the number of detectors in the bank, :math:`N_p` is the number of reference peaks, and
        :math:`m_{i,j}` is the mask for peak :math:`j` and detector :math:`i`. The mask evaluates to 1 if the
        detector is defective or the peak is missing in the detector, otherwise the mask evaluates to zero.

        There's an implicit one-to-correspondence between array index of ``difc`` and workspace index of ``wks_name``,
        that is, between row index of the input TOFS table and workspace index of ``wks_name``.

        @param x_0 :: list of length 3 (new XYZ coordinates of the component) or length 6 (XYZ and rotation coords)
        @param wks_name :: name of a workspace with an embedded instrument. The instrument will be adjusted according to
            the new coordinates ``x_0`` for instrument component ``component``. It's pixel spectra will contain the new DIFC
        @param component :: name of the instrument component to be optimized
        @param firstIndex :: workspace index of first index of ``difc`` array to be considered when comparing old
            and new DIFC values. When fitting the source or sample, this is the first spectrum index.
        @param lastIndex ::  workspace index of last index of ``difc`` array to be considered when comparing old
            and new DIFC values. When fitting the source or sample, this is the last row number of the input
            TOFS table.

        @return Chi-square value between old and new DIFC values for the unmasked spectra
        """
        xmap = self._mapOptions(
            x_0)  # pad null rotations when x_0 contains only translations

        if self._move:
            api.MoveInstrumentComponent(wks_name,
                                        component,
                                        X=xmap[0],
                                        Y=xmap[1],
                                        Z=xmap[2],
                                        RelativePosition=False,
                                        EnableLogging=False)

        if self._rotate:
            (rotw, rotx, roty,
             rotz) = self._eulerToAngleAxis(xmap[3], xmap[4], xmap[5],
                                            self._eulerConvention)  # YZX
            api.RotateInstrumentComponent(wks_name,
                                          component,
                                          X=rotx,
                                          Y=roty,
                                          Z=rotz,
                                          Angle=rotw,
                                          RelativeRotation=False,
                                          EnableLogging=False)

        api.CalculateDIFC(InputWorkspace=wks_name,
                          OutputWorkspace=wks_name,
                          EnableLogging=False)
        difc = api.mtd[wks_name].extractY().flatten()[firstIndex:lastIndex + 1]
        peaks_d = self.peaks_tof[
            firstIndex:lastIndex +
            1] / difc[:, np.newaxis]  # peak centers in d-spacing units

        # calculate the fractional peak center deviations, then sum their absolute values
        return np.sum(np.abs((peaks_d - self.peaks_ref) / self.peaks_ref))